Various serialization patches from Cesar.
[mono.git] / mcs / class / System / System.Text.RegularExpressions / regex.cs
1 //\r
2 // assembly:    System\r
3 // namespace:   System.Text.RegularExpressions\r
4 // file:        regex.cs\r
5 //\r
6 // author:      Dan Lewis (dlewis@gmx.co.uk)\r
7 //              (c) 2002\r
8 \r
9 using System;\r
10 using System.Text;\r
11 using System.Collections;\r
12 using System.Reflection;\r
13 using System.Reflection.Emit;\r
14 using System.Runtime.Serialization;\r
15 \r
16 using RegularExpression = System.Text.RegularExpressions.Syntax.RegularExpression;\r
17 using Parser = System.Text.RegularExpressions.Syntax.Parser;\r
18 \r
19 namespace System.Text.RegularExpressions {\r
20         \r
21         public delegate string MatchEvaluator (Match match);\r
22 \r
23         [Flags]\r
24         public enum RegexOptions {\r
25                 None                            = 0x000,\r
26                 IgnoreCase                      = 0x001,\r
27                 Multiline                       = 0x002,\r
28                 ExplicitCapture                 = 0x004,\r
29                 Compiled                        = 0x008,\r
30                 Singleline                      = 0x010,\r
31                 IgnorePatternWhitespace         = 0x020,\r
32                 RightToLeft                     = 0x040,\r
33                 ECMAScript                      = 0x100\r
34         }\r
35         \r
36         [Serializable]\r
37         public class Regex : ISerializable {\r
38                 public static void CompileToAssembly\r
39                         (RegexCompilationInfo[] regexes, AssemblyName aname)\r
40                 {\r
41                         throw new Exception ("Not implemented.");\r
42                 }\r
43 \r
44                 public static void CompileToAssembly\r
45                         (RegexCompilationInfo[] regexes, AssemblyName aname,\r
46                          CustomAttributeBuilder[] attribs)\r
47                 {\r
48                         throw new Exception ("Not implemented.");\r
49                 }\r
50 \r
51                 public static void CompileToAssembly\r
52                         (RegexCompilationInfo[] regexes, AssemblyName aname,\r
53                          CustomAttributeBuilder[] attribs, string resourceFile)\r
54                 {\r
55                         throw new Exception ("Not implemented.");\r
56                 }\r
57                 \r
58                 public static string Escape (string str) {\r
59                         return Parser.Escape (str);\r
60                 }\r
61 \r
62                 public static string Unescape (string str) {\r
63                         return Parser.Unescape (str);\r
64                 }\r
65 \r
66                 public static bool IsMatch (string input, string pattern) {\r
67                         return IsMatch (input, pattern, RegexOptions.None);\r
68                 }\r
69 \r
70                 public static bool IsMatch (string input, string pattern, RegexOptions options) {\r
71                         Regex re = new Regex (pattern, options);\r
72                         return re.IsMatch (input);\r
73                 }\r
74 \r
75                 public static Match Match (string input, string pattern) {\r
76                         return Regex.Match (input, pattern, RegexOptions.None);\r
77                 }\r
78 \r
79                 public static Match Match (string input, string pattern, RegexOptions options) {\r
80                         Regex re = new Regex (pattern, options);\r
81                         return re.Match (input);\r
82                 }\r
83 \r
84                 public static MatchCollection Matches (string input, string pattern) {\r
85                         return Matches (input, pattern, RegexOptions.None);\r
86                 }\r
87 \r
88                 public static MatchCollection Matches (string input, string pattern, RegexOptions options) {\r
89                         Regex re = new Regex (pattern, options);\r
90                         return re.Matches (input);\r
91                 }\r
92 \r
93                 public static string Replace\r
94                         (string input, string pattern, MatchEvaluator evaluator)\r
95                 {\r
96                         return Regex.Replace (input, pattern, evaluator, RegexOptions.None);\r
97                 }\r
98 \r
99                 public static string Replace\r
100                         (string input, string pattern, MatchEvaluator evaluator,\r
101                          RegexOptions options)\r
102                 {\r
103                         Regex re = new Regex (pattern, options);\r
104                         return re.Replace (input, evaluator);\r
105                 }\r
106 \r
107                 public static string Replace\r
108                         (string input, string pattern, string replacement)\r
109                 {\r
110                         return Regex.Replace (input, pattern, replacement, RegexOptions.None);\r
111                 }\r
112 \r
113                 public static string Replace\r
114                         (string input, string pattern, string replacement,\r
115                          RegexOptions options)\r
116                 {\r
117                         Regex re = new Regex (pattern, options);\r
118                         return re.Replace (input, replacement);\r
119                 }\r
120 \r
121                 public static string[] Split (string input, string pattern) {\r
122                         return Regex.Split (input, pattern, RegexOptions.None);\r
123                 }\r
124 \r
125                 public static string[] Split (string input, string pattern, RegexOptions options) {\r
126                         Regex re = new Regex (input, options);\r
127                         return re.Split (input);\r
128                 }\r
129 \r
130                 // private\r
131 \r
132                 private static FactoryCache cache = new FactoryCache (200);     // TODO put some meaningful number here\r
133 \r
134                 // constructors\r
135 \r
136                 protected Regex () {\r
137                         // XXX what's this constructor for?\r
138                 }\r
139 \r
140                 public Regex (string pattern) : this (pattern, RegexOptions.None) {\r
141                 }\r
142 \r
143                 public Regex (string pattern, RegexOptions options) {\r
144                         this.pattern = pattern;\r
145                         this.options = options;\r
146                 \r
147                         this.factory = cache.Lookup (pattern, options);\r
148 \r
149                         // parse and install group mapping\r
150 \r
151                         Parser psr = new Parser ();\r
152                         RegularExpression re = psr.ParseRegularExpression (pattern, options);\r
153                         this.group_count = re.GroupCount;\r
154                         this.mapping = psr.GetMapping ();\r
155 \r
156                         if (this.factory == null) {\r
157                                 // compile\r
158                                 \r
159                                 ICompiler cmp;\r
160                                 if ((options & RegexOptions.Compiled) != 0)\r
161                                         throw new Exception ("Not implemented.");\r
162                                         //cmp = new CILCompiler ();\r
163                                 else\r
164                                         cmp = new PatternCompiler ();\r
165 \r
166                                 re.Compile (cmp, RightToLeft);\r
167 \r
168                                 // install machine factory and add to pattern cache\r
169 \r
170                                 this.factory = cmp.GetMachineFactory ();\r
171                                 cache.Add (pattern, options, this.factory);\r
172                         }\r
173                 }\r
174 \r
175                 protected Regex (SerializationInfo info, StreamingContext context) :\r
176                         this (info.GetString ("pattern"), \r
177                               (RegexOptions) info.GetValue ("options", typeof (RegexOptions))) {                        \r
178                 }\r
179 \r
180 \r
181                 // public instance properties\r
182                 \r
183                 public RegexOptions Options {\r
184                         get { return options; }\r
185                 }\r
186 \r
187                 public bool RightToLeft {\r
188                         get { return (options & RegexOptions.RightToLeft) != 0; }\r
189                 }\r
190 \r
191                 // public instance methods\r
192                 \r
193                 public string[] GetGroupNames () {\r
194                         string[] names = new string[mapping.Count];\r
195                         mapping.Keys.CopyTo (names, 0);\r
196 \r
197                         return names;\r
198                 }\r
199 \r
200                 public int[] GetGroupNumbers () {\r
201                         int[] numbers = new int[mapping.Count];\r
202                         mapping.Values.CopyTo (numbers, 0);\r
203 \r
204                         return numbers;\r
205                 }\r
206 \r
207                 public string GroupNameFromNumber (int i) {\r
208                         if (i >= group_count)\r
209                                 return "";\r
210                 \r
211                         foreach (string name in mapping.Keys) {\r
212                                 if ((int)mapping[name] == i)\r
213                                         return name;\r
214                         }\r
215 \r
216                         return "";\r
217                 }\r
218 \r
219                 public int GroupNumberFromName (string name) {\r
220                         if (mapping.Contains (name))\r
221                                 return (int)mapping[name];\r
222 \r
223                         return -1;\r
224                 }\r
225 \r
226                 // match methods\r
227                 \r
228                 public bool IsMatch (string input) {\r
229                         return IsMatch (input, 0);\r
230                 }\r
231 \r
232                 public bool IsMatch (string input, int startat) {\r
233                         return Match (input, startat).Success;\r
234                 }\r
235 \r
236                 public Match Match (string input) {\r
237                         return Match (input, 0);\r
238                 }\r
239 \r
240                 public Match Match (string input, int startat) {\r
241                         return CreateMachine ().Scan (this, input, startat, input.Length);\r
242                 }\r
243 \r
244                 public Match Match (string input, int startat, int length) {\r
245                         return CreateMachine ().Scan (this, input, startat, startat + length);\r
246                 }\r
247 \r
248                 public MatchCollection Matches (string input) {\r
249                         return Matches (input, 0);\r
250                 }\r
251 \r
252                 public MatchCollection Matches (string input, int startat) {\r
253                         MatchCollection ms = new MatchCollection ();\r
254                         Match m = Match (input, startat);\r
255                         while (m.Success) {\r
256                                 ms.Add (m);\r
257                                 m = m.NextMatch ();\r
258                         }\r
259 \r
260                         return ms;\r
261                 }\r
262 \r
263                 // replace methods\r
264 \r
265                 public string Replace (string input, MatchEvaluator evaluator) {\r
266                         return Replace (input, evaluator, Int32.MaxValue, 0);\r
267                 }\r
268 \r
269                 public string Replace (string input, MatchEvaluator evaluator, int count) {\r
270                         return Replace (input, evaluator, count, 0);\r
271                 }\r
272 \r
273                 public string Replace (string input, MatchEvaluator evaluator, int count, int startat)\r
274                 {\r
275                         StringBuilder result = new StringBuilder ();\r
276                         int ptr = startat;\r
277 \r
278                         Match m = Match (input, startat);\r
279                         while (m.Success && count -- > 0) {\r
280                                 result.Append (input.Substring (ptr, m.Index - ptr));\r
281                                 result.Append (evaluator (m));\r
282 \r
283                                 ptr = m.Index + m.Length;\r
284                                 m = m.NextMatch ();\r
285                         }\r
286                         result.Append (input.Substring (ptr));\r
287 \r
288                         return result.ToString ();\r
289                 }\r
290 \r
291                 public string Replace (string input, string replacement) {\r
292                         return Replace (input, replacement, Int32.MaxValue, 0);\r
293                 }\r
294 \r
295                 public string Replace (string input, string replacement, int count) {\r
296                         return Replace (input, replacement, count, 0);\r
297                 }\r
298 \r
299                 public string Replace (string input, string replacement, int count, int startat) {\r
300                         ReplacementEvaluator ev = new ReplacementEvaluator (this, replacement);\r
301                         return Replace (input, new MatchEvaluator (ev.Evaluate), count, startat);\r
302                 }\r
303 \r
304                 // split methods\r
305 \r
306                 public string[] Split (string input) {\r
307                         return Split (input, Int32.MaxValue, 0);\r
308                 }\r
309 \r
310                 public string[] Split (string input, int count) {\r
311                         return Split (input, count, 0);\r
312                 }\r
313 \r
314                 public string[] Split (string input, int count, int startat) {\r
315                         ArrayList splits = new ArrayList ();\r
316                         if (count == 0)\r
317                                 count = Int32.MaxValue;\r
318 \r
319                         int ptr = startat;\r
320                         while (count -- > 0) {\r
321                                 Match m = Match (input, ptr);\r
322                                 if (!m.Success)\r
323                                         break;\r
324                         \r
325                                 splits.Add (input.Substring (ptr, m.Index - ptr));\r
326                                 ptr = m.Index + m.Length;\r
327                         }\r
328 \r
329                         if (count > 0)\r
330                                 splits.Add (input.Substring (ptr));\r
331 \r
332                         string[] result = new string[splits.Count];\r
333                         splits.CopyTo (result);\r
334                         return result;\r
335                 }\r
336 \r
337                 // object methods\r
338                 \r
339                 public override string ToString () {\r
340                         return pattern;\r
341                 }\r
342 \r
343                 // ISerializable interface\r
344                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context) {\r
345                         info.AddValue ("pattern", this.ToString (), typeof (string));\r
346                         info.AddValue ("options", this.Options, typeof (RegexOptions));\r
347                 }\r
348 \r
349                 // internal\r
350 \r
351                 internal int GroupCount {\r
352                         get { return group_count; }\r
353                 }\r
354 \r
355                 // private\r
356 \r
357                 private IMachine CreateMachine () {\r
358                         return factory.NewInstance ();\r
359                 }\r
360 \r
361                 protected internal string pattern;\r
362                 private RegexOptions options;\r
363 \r
364                 private IMachineFactory factory;\r
365                 private IDictionary mapping;\r
366                 private int group_count;\r
367         }\r
368 \r
369         [Serializable]\r
370         public class RegexCompilationInfo {\r
371                 public RegexCompilationInfo (string pattern, RegexOptions options, string name, string full_namespace, bool is_public) {\r
372                         this.pattern = pattern;\r
373                         this.options = options;\r
374                         this.name = name;\r
375                         this.full_namespace = full_namespace;\r
376                         this.is_public = is_public;\r
377                 }\r
378 \r
379                 public bool IsPublic {\r
380                         get { return is_public; }\r
381                         set { is_public = value; }\r
382                 }\r
383 \r
384                 public string Name {\r
385                         get { return name; }\r
386                         set { name = value; }\r
387                 }\r
388 \r
389                 public string Namespace {\r
390                         get { return full_namespace; }\r
391                         set { full_namespace = value; }\r
392                 }\r
393 \r
394                 public RegexOptions Options {\r
395                         get { return options; }\r
396                         set { options = value; }\r
397                 }\r
398 \r
399                 public string Pattern {\r
400                         get { return pattern; }\r
401                         set { pattern = value; }\r
402                 }\r
403 \r
404                 // private\r
405 \r
406                 private string pattern, name, full_namespace;\r
407                 private RegexOptions options;\r
408                 private bool is_public;\r
409         }\r
410 }\r