regex.cs 9.9 KB

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