}\r
\r
private Expression ParseCharacterClass (RegexOptions options) {\r
- bool negate;\r
+ bool negate, ecma;\r
if (pattern[ptr] == '^') {\r
negate = true;\r
++ ptr;\r
else\r
negate = false;\r
\r
+ ecma = IsECMAScript (options);\r
CharacterClass cls = new CharacterClass (negate, IsIgnoreCase (options));\r
\r
if (pattern[ptr] == ']') {\r
switch (c) {\r
case 'b': c = '\b'; break;\r
\r
- case 'd': cls.AddCategory (Category.Digit, false); last = -1; continue;\r
- case 'w': cls.AddCategory (Category.Word, false); last = -1; continue;\r
- case 's': cls.AddCategory (Category.WhiteSpace, false); last = -1; continue;\r
- case 'p': cls.AddCategory (ParseUnicodeCategory (), true); last = -1; continue;\r
- case 'D': cls.AddCategory (Category.Digit, true); last = -1; continue;\r
- case 'W': cls.AddCategory (Category.Word, true); last = -1; continue;\r
- case 'S': cls.AddCategory (Category.WhiteSpace, true); last = -1; continue;\r
- case 'P': cls.AddCategory (ParseUnicodeCategory (), true); last = -1; continue;\r
+ case 'd':\r
+ cls.AddCategory (ecma ? Category.EcmaDigit : Category.Digit, false);\r
+ last = -1;\r
+ continue;\r
+ \r
+ case 'w':\r
+ cls.AddCategory (ecma ? Category.EcmaWord : Category.Word, false);\r
+ last = -1;\r
+ continue;\r
+ \r
+ case 's':\r
+ cls.AddCategory (ecma ? Category.EcmaWhiteSpace : Category.WhiteSpace, false);\r
+ last = -1;\r
+ continue;\r
+ \r
+ case 'p':\r
+ cls.AddCategory (ParseUnicodeCategory (), false); // ignore ecma\r
+ last = -1;\r
+ continue;\r
+ \r
+ case 'D':\r
+ cls.AddCategory (ecma ? Category.EcmaDigit : Category.Digit, true);\r
+ last = -1;\r
+ continue;\r
+ \r
+ case 'W':\r
+ cls.AddCategory (ecma ? Category.EcmaWord : Category.Word, true);\r
+ last = -1;\r
+ continue;\r
+ \r
+ case 'S':\r
+ cls.AddCategory (ecma ? Category.EcmaWhiteSpace : Category.WhiteSpace, true);\r
+ last = -1;\r
+ continue;\r
+ \r
+ case 'P':\r
+ cls.AddCategory (ParseUnicodeCategory (), true);\r
+ last = -1;\r
+ continue;\r
\r
default: break; // add escaped character\r
}\r
\r
private Expression ParseSpecial (RegexOptions options) {\r
int p = ptr;\r
+ bool ecma = IsECMAScript (options);\r
Expression expr = null;\r
\r
switch (pattern[ptr ++]) {\r
\r
// categories\r
\r
- case 'd': expr = new CharacterClass (Category.Digit, false); break;\r
- case 'w': expr = new CharacterClass (Category.Word, false); break;\r
- case 's': expr = new CharacterClass (Category.WhiteSpace, false); break;\r
- case 'D': expr = new CharacterClass (Category.Digit, true); break;\r
- case 'W': expr = new CharacterClass (Category.Word, true); break;\r
- case 'S': expr = new CharacterClass (Category.WhiteSpace, true); break;\r
- case 'p': expr = new CharacterClass (ParseUnicodeCategory (), true); break;\r
- case 'P': expr = new CharacterClass (ParseUnicodeCategory (), false); break;\r
+ case 'd':\r
+ expr = new CharacterClass (ecma ? Category.EcmaDigit : Category.Digit, false);\r
+ break;\r
+ \r
+ case 'w':\r
+ expr = new CharacterClass (ecma ? Category.EcmaWord : Category.Word, false);\r
+ break;\r
+ \r
+ case 's':\r
+ expr = new CharacterClass (ecma ? Category.EcmaWhiteSpace : Category.WhiteSpace, false);\r
+ break;\r
+ \r
+ case 'p':\r
+ // this is odd - ECMAScript isn't supposed to support Unicode,\r
+ // yet \p{..} compiles and runs under the MS implementation\r
+ // identically to canonical mode. That's why I'm ignoring the\r
+ // value of ecma here.\r
+ \r
+ expr = new CharacterClass (ParseUnicodeCategory (), false);\r
+ break;\r
+ \r
+ case 'D':\r
+ expr = new CharacterClass (ecma ? Category.EcmaDigit : Category.Digit, true);\r
+ break;\r
+ \r
+ case 'W':\r
+ expr = new CharacterClass (ecma ? Category.EcmaWord : Category.Word, true);\r
+ break;\r
+ \r
+ case 'S':\r
+ expr = new CharacterClass (ecma ? Category.EcmaWhiteSpace : Category.WhiteSpace, true);\r
+ break;\r
+ \r
+ case 'P':\r
+ expr = new CharacterClass (ParseUnicodeCategory (), true);\r
+ break;\r
\r
// positions\r
\r
return (options & RegexOptions.RightToLeft) != 0;\r
}\r
\r
+ private static bool IsECMAScript (RegexOptions options) {\r
+ return (options & RegexOptions.ECMAScript) != 0;\r
+ }\r
+\r
// exception creation\r
\r
private ArgumentException NewParseException (string msg) {\r