C # uses the Regular Expression of python syntax.
Because of the project requirements, we need to use python Regular Expressions in c #. The first method we use is ironpython.
However, compilation on ios fails. Fortunately, ironpython is an open-source project, so I started to study the code.
Because the functions I need are very simple, the final code is just to determine whether the input string matches the python regular expression I passed in.
Parse some codes and use them directly:
/*************************************** **************************************** Copyright (c) microsoft Corporation. ** This source code is subject to terms and conditions of the Microsoft Public * License. A copy of the license can be found in the License.html file at the * root of this distribution. if you cannot locate the Microsoft Public * License, please send an email to dlr@microsoft.com. by using this source * code in any fashion, you are agreeing to be bound by the terms of the * Microsoft Public License. ** You must not remove this notice, or any other, from this software. **************************************** * **********************************/using System; using System. text; using System. text. regularExpressions ;////// Python Regular Expression parsing // By ZeaLotSean ///Public static class PythonRegex {# region CONSTANTS // short forms // public static object I = 0x02; // public static object L = 0x04; // public static object M = 0x08; // public static object S = 0x10; // public static object U = 0x20; // public static object X = 0x40; // long forms public static object IGNORECASE = 0x02; public static object LOCALE = 0x04; public static object MULTILINE = 0x08; public static object DOTALL = 0x10; public static object UNICODE = 0x20; public static object VERBOSE = 0x40; # endregion ////// Compile a regular expression /////////
Public static Python_Pattern Compile (string _ pattern) {return new Python_Pattern (_ pattern, 0, true);} public static bool isMatched (string _ pattern, string _ str) {return isMatched (_ pattern, _ str, 0);} public static bool isMatched (string _ pattern, string _ str, int flags) {return new Python_Pattern (_ pattern, flags ). isMatched (_ str );}////// Compiled reg-ex pattern ///Public class Python_Pattern {internal Regex m_re; internal ParsedRegex m_pre; public Python_Pattern (string pattern): this (pattern, 0) {} public Python_Pattern (string pattern, int flags ): this (pattern, flags, false) {} public Python_Pattern (string pattern, int flags, bool compiled) {m_pre = PreParseRegex (pattern); RegexOptions opts = FlagsToOption (flags); this. m_re = new Regex (m_pre.Pattern, o Pts | (compiled? RegexOptions. Compiled: RegexOptions. None ));}////// Query whether the input string matches the regular expression /////////
Public bool isMatched (string _ str) {return m_re.Match (_ str ). success;} public string Pattern {get {return m_pre.UserPattern ;}} private static RegexOptions FlagsToOption (int flags) {RegexOptions opts = RegexOptions. none; if (flags & (int) IGNORECASE )! = 0) opts | = RegexOptions. IgnoreCase; if (flags & (int) MULTILINE )! = 0) opts | = RegexOptions. Multiline; if (flags & (int) LOCALE) = 0) opts & = (~ RegexOptions. CultureInvariant); if (flags & (int) DOTALL )! = 0) opts | = RegexOptions. Singleline; if (flags & (int) VERBOSE )! = 0) opts | = RegexOptions. ignorePatternWhitespace; return opts;} internal class ParsedRegex {public ParsedRegex (string pattern) {this. userPattern = pattern;} public string UserPattern; public string Pattern; public RegexOptions Options = RegexOptions. cultureInvariant ;}////// Preparses a regular expression text returning a ParsedRegex class // that can be used for further regular expressions. /// input a python Regular Expression and return a c # available format ///Private static ParsedRegex PreParseRegex (string pattern) {ParsedRegex res = new ParsedRegex (pattern); // string newPattern; int cur = 0, nameIndex; int curGroup = 0; bool containsNamedGroup = false; for (;) {nameIndex = pattern. indexOf (, cur); if (nameIndex> 0 & pattern [nameIndex-1] = '\') {int curIndex = nameIndex-2; int backslashCount = 1; while (curIndex> = 0 & pattern [curIndex] = '\') {BackslashCount ++; curIndex --;} // odd number of back slashes, this is an optional // paren that we shoshould ignore. if (backslashCount & 0x01 )! = 0) {cur ++; continue ;}} if (nameIndex =-1) break; if (nameIndex = pattern. length-1) break; switch (pattern [++ nameIndex]) {case '? ': // Extension syntax if (nameIndex = pattern. length-1) {return null;} switch (pattern [++ nameIndex]) {case 'p': // named regex ,. NET doesn't expect CT the P so we'll remove it; // also, once we see a named group I. e .? P then we need to start artificially // naming all unnamed groups from then on --- this is to get around the fact that // the CLR RegEx support orders all the unnamed groups before all the named // groups, even if the named groups are before the unnamed ones in the pattern; // the artificial naming preserves the order of the groups and thus the order of // the matches if (nameIndex + 1 <pattern. leng Th & pattern [nameIndex + 1] = ') {// match whatever was previusly matched by the named group // remove (? P = pattern. remove (nameIndex-2, 4); pattern = pattern. insert (nameIndex-2, \ k <); int tmpIndex = nameIndex; while (tmpIndex <pattern. length & pattern [tmpIndex]! = ') TmpIndex ++; if (tmpIndex = pattern. length) {return null;} pattern = pattern. substring (0, tmpIndex) +> + pattern. substring (tmpIndex + 1);} else {containsNamedGroup = true; pattern = pattern. remove (nameIndex, 1);} break; case 'I': res. options | = RegexOptions. ignoreCase; break; case 'l': res. options & = ~ (RegexOptions. cultureInvariant); break; case 'M': res. options | = RegexOptions. multiline; break; case's ': res. options | = RegexOptions. singleline; break; case 'U': break; case 'X': res. options | = RegexOptions. ignorePatternWhitespace; break; case ': break; // non-capturing case' = ': break; // look ahead assertion case' <': break; // positive look behind assertion case '! ': Break; // negative look ahead assertion case' #': break; // inline comment case' (': // yes/no if group exists, we don't support this default: {return null ;}} break; default: // just another group curGroup ++; if (containsNamedGroup) {// need to name this unnamed group pattern = pattern. insert (nameIndex ,?
);} Break;} cur = nameIndex;} cur = 0; for (;) {nameIndex = pattern. indexOf ('\', cur); if (nameIndex =-1 | nameIndex = pattern. length-1) break; char curChar = pattern [++ nameIndex]; switch (curChar) {case 'X': case 'U': case 'A ': case 'B': case 'E': case 'F': case 'N': case 'r': case 'T': case 'V': case 'C ': case's ': case 'W': case 'p': case 's': case 'D ': case 'Z': // known escape sequences, leave escaped. break; case '\': // escaping a \ cur + = 2; break; default: System. globalization. unicodeCategory charClass = Char. getUnicodeCategory (curChar); switch (charClass) {// recognized word characters, always unescape. case System. globalization. unicodeCategory. modifierLetter: case System. globalization. unicodeCategory. lowercaseLetter: case System. globalization. unicodeCategory. uppercaseLetter: case System. globalization. unicodeCategory. titlecaseLetter: case System. globalization. unicodeCategory. otherLetter: case System. globalization. unicodeCategory. letterNumber: case System. globalization. unicodeCategory. otherNumber: case System. globalization. unicodeCategory. connectorPunctuation: pattern = pattern. remove (nameIndex-1, 1); break; case System. globalization. unicodeCategory. decimalDigitNumber: // actually don't want to scape '', ''etc. which are references to groups break;} cur ++;} res. pattern = pattern; return res;} static Random r = new Random (DateTime. now. millisecond); private static string GetRandomString () {return r. next (Int32.MaxValue/2, Int32.MaxValue ). toString ();}}