3 // namespace: System.Text.RegularExpressions
\r
6 // author: Dan Lewis (dlewis@gmx.co.uk)
\r
11 using System.Collections;
\r
12 using System.Reflection;
\r
13 using System.Reflection.Emit;
\r
14 using System.Runtime.Serialization;
\r
16 using RegularExpression = System.Text.RegularExpressions.Syntax.RegularExpression;
\r
17 using Parser = System.Text.RegularExpressions.Syntax.Parser;
\r
19 namespace System.Text.RegularExpressions {
\r
21 public delegate string MatchEvaluator (Match match);
\r
24 public enum RegexOptions {
\r
28 ExplicitCapture = 0x004,
\r
31 IgnorePatternWhitespace = 0x020,
\r
32 RightToLeft = 0x040,
\r
37 public class Regex : ISerializable {
\r
38 public static void CompileToAssembly
\r
39 (RegexCompilationInfo[] regexes, AssemblyName aname)
\r
41 throw new Exception ("Not implemented.");
\r
44 public static void CompileToAssembly
\r
45 (RegexCompilationInfo[] regexes, AssemblyName aname,
\r
46 CustomAttributeBuilder[] attribs)
\r
48 throw new Exception ("Not implemented.");
\r
51 public static void CompileToAssembly
\r
52 (RegexCompilationInfo[] regexes, AssemblyName aname,
\r
53 CustomAttributeBuilder[] attribs, string resourceFile)
\r
55 throw new Exception ("Not implemented.");
\r
58 public static string Escape (string str) {
\r
59 return Parser.Escape (str);
\r
62 public static string Unescape (string str) {
\r
63 return Parser.Unescape (str);
\r
66 public static bool IsMatch (string input, string pattern) {
\r
67 return IsMatch (input, pattern, RegexOptions.None);
\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
75 public static Match Match (string input, string pattern) {
\r
76 return Regex.Match (input, pattern, RegexOptions.None);
\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
84 public static MatchCollection Matches (string input, string pattern) {
\r
85 return Matches (input, pattern, RegexOptions.None);
\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
93 public static string Replace
\r
94 (string input, string pattern, MatchEvaluator evaluator)
\r
96 return Regex.Replace (input, pattern, evaluator, RegexOptions.None);
\r
99 public static string Replace
\r
100 (string input, string pattern, MatchEvaluator evaluator,
\r
101 RegexOptions options)
\r
103 Regex re = new Regex (pattern, options);
\r
104 return re.Replace (input, evaluator);
\r
107 public static string Replace
\r
108 (string input, string pattern, string replacement)
\r
110 return Regex.Replace (input, pattern, replacement, RegexOptions.None);
\r
113 public static string Replace
\r
114 (string input, string pattern, string replacement,
\r
115 RegexOptions options)
\r
117 Regex re = new Regex (pattern, options);
\r
118 return re.Replace (input, replacement);
\r
121 public static string[] Split (string input, string pattern) {
\r
122 return Regex.Split (input, pattern, RegexOptions.None);
\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
132 private static FactoryCache cache = new FactoryCache (200); // TODO put some meaningful number here
\r
136 protected Regex () {
\r
137 // XXX what's this constructor for?
\r
140 public Regex (string pattern) : this (pattern, RegexOptions.None) {
\r
143 public Regex (string pattern, RegexOptions options) {
\r
144 this.pattern = pattern;
\r
145 this.options = options;
\r
147 this.factory = cache.Lookup (pattern, options);
\r
149 // parse and install group mapping
\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
156 if (this.factory == null) {
\r
160 if ((options & RegexOptions.Compiled) != 0)
\r
161 throw new Exception ("Not implemented.");
\r
162 //cmp = new CILCompiler ();
\r
164 cmp = new PatternCompiler ();
\r
166 re.Compile (cmp, RightToLeft);
\r
168 // install machine factory and add to pattern cache
\r
170 this.factory = cmp.GetMachineFactory ();
\r
171 cache.Add (pattern, options, this.factory);
\r
175 protected Regex (SerializationInfo info, StreamingContext context) :
\r
176 this (info.GetString ("pattern"),
\r
177 (RegexOptions) info.GetValue ("options", typeof (RegexOptions))) {
\r
181 // public instance properties
\r
183 public RegexOptions Options {
\r
184 get { return options; }
\r
187 public bool RightToLeft {
\r
188 get { return (options & RegexOptions.RightToLeft) != 0; }
\r
191 // public instance methods
\r
193 public string[] GetGroupNames () {
\r
194 string[] names = new string[mapping.Count];
\r
195 mapping.Keys.CopyTo (names, 0);
\r
200 public int[] GetGroupNumbers () {
\r
201 int[] numbers = new int[mapping.Count];
\r
202 mapping.Values.CopyTo (numbers, 0);
\r
207 public string GroupNameFromNumber (int i) {
\r
208 if (i >= group_count)
\r
211 foreach (string name in mapping.Keys) {
\r
212 if ((int)mapping[name] == i)
\r
219 public int GroupNumberFromName (string name) {
\r
220 if (mapping.Contains (name))
\r
221 return (int)mapping[name];
\r
228 public bool IsMatch (string input) {
\r
229 return IsMatch (input, 0);
\r
232 public bool IsMatch (string input, int startat) {
\r
233 return Match (input, startat).Success;
\r
236 public Match Match (string input) {
\r
237 return Match (input, 0);
\r
240 public Match Match (string input, int startat) {
\r
241 return CreateMachine ().Scan (this, input, startat, input.Length);
\r
244 public Match Match (string input, int startat, int length) {
\r
245 return CreateMachine ().Scan (this, input, startat, startat + length);
\r
248 public MatchCollection Matches (string input) {
\r
249 return Matches (input, 0);
\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
257 m = m.NextMatch ();
\r
265 public string Replace (string input, MatchEvaluator evaluator) {
\r
266 return Replace (input, evaluator, Int32.MaxValue, 0);
\r
269 public string Replace (string input, MatchEvaluator evaluator, int count) {
\r
270 return Replace (input, evaluator, count, 0);
\r
273 public string Replace (string input, MatchEvaluator evaluator, int count, int startat)
\r
275 StringBuilder result = new StringBuilder ();
\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
283 ptr = m.Index + m.Length;
\r
284 m = m.NextMatch ();
\r
286 result.Append (input.Substring (ptr));
\r
288 return result.ToString ();
\r
291 public string Replace (string input, string replacement) {
\r
292 return Replace (input, replacement, Int32.MaxValue, 0);
\r
295 public string Replace (string input, string replacement, int count) {
\r
296 return Replace (input, replacement, count, 0);
\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
306 public string[] Split (string input) {
\r
307 return Split (input, Int32.MaxValue, 0);
\r
310 public string[] Split (string input, int count) {
\r
311 return Split (input, count, 0);
\r
314 public string[] Split (string input, int count, int startat) {
\r
315 ArrayList splits = new ArrayList ();
\r
317 count = Int32.MaxValue;
\r
320 while (count -- > 0) {
\r
321 Match m = Match (input, ptr);
\r
325 splits.Add (input.Substring (ptr, m.Index - ptr));
\r
326 ptr = m.Index + m.Length;
\r
330 splits.Add (input.Substring (ptr));
\r
332 string[] result = new string[splits.Count];
\r
333 splits.CopyTo (result);
\r
339 public override string ToString () {
\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
351 internal int GroupCount {
\r
352 get { return group_count; }
\r
357 private IMachine CreateMachine () {
\r
358 return factory.NewInstance ();
\r
361 protected internal string pattern;
\r
362 private RegexOptions options;
\r
364 private IMachineFactory factory;
\r
365 private IDictionary mapping;
\r
366 private int group_count;
\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
375 this.full_namespace = full_namespace;
\r
376 this.is_public = is_public;
\r
379 public bool IsPublic {
\r
380 get { return is_public; }
\r
381 set { is_public = value; }
\r
384 public string Name {
\r
385 get { return name; }
\r
386 set { name = value; }
\r
389 public string Namespace {
\r
390 get { return full_namespace; }
\r
391 set { full_namespace = value; }
\r
394 public RegexOptions Options {
\r
395 get { return options; }
\r
396 set { options = value; }
\r
399 public string Pattern {
\r
400 get { return pattern; }
\r
401 set { pattern = value; }
\r
406 private string pattern, name, full_namespace;
\r
407 private RegexOptions options;
\r
408 private bool is_public;
\r