为啥运行带有 ECMAScript 风格支持的 .Net 正则表达式 \A

Posted

技术标签:

【中文标题】为啥运行带有 ECMAScript 风格支持的 .Net 正则表达式 \\A【英文标题】:Why running .Net Regex with ECMAScript flavor support \A为什么运行带有 ECMAScript 风格支持的 .Net 正则表达式 \A 【发布时间】:2021-10-17 21:56:55 【问题描述】:

我有一个.NetStandard2.1 C# 应用程序,它需要以ECMAScript 风格运行Regex

根据MSDN documentation,我可以使用RegexOptions.ECMAScript

为表达式启用符合 ECMAScript 的行为。

我知道ECMAScript 不支持\A 锚点(根据link 和当我使用ECMAScript 选项尝试Regex101 时)。但似乎.Net 确实支持它。示例:

Regex emcaRegex = new Regex(@"\A\d3", RegexOptions.ECMAScript);
var matches =  emcaRegex.Matches("901-333-");

Console.WriteLine($"number of matches: matches.Count"); // number of matches: 1
Console.WriteLine($"The match: matches[0]"); // The match: 901

我希望得到不匹配的东西,我错过了什么?

【问题讨论】:

【参考方案1】:

您需要在"ECMAScript Matching Behavior" article 中进一步寻找答案。

此选项不会重新定义 .NET 特定的锚点含义,它们仍然受支持。

ECMAScript 和规范正则表达式的行为在三个方面有所不同:字符类语法、自引用捕获组以及八进制与反向引用解释。

字符类语法。因为规范正则表达式支持 Unicode 而 ECMAScript 不支持,所以 ECMAScript 中的字符类具有更有限的语法,并且某些字符类语言元素具有不同的含义。例如,ECMAScript 不支持 Unicode 类别或块元素 \p\P 等语言元素。同样,匹配单词字符的\w 元素在使用ECMAScript 时等效于[a-zA-Z_0-9] 字符类,在使用规范行为时等效于[\pLl\pLu\pLt\pLo\pNd\pPc\pLm]。如需更多信息,请参阅Character Classes。

自引用捕获组。必须在每次捕获迭代时更新具有自身反向引用的正则表达式捕获类。

解决八进制转义和反向引用之间的歧义。

Regular expression Canonical behavior ECMAScript behavior
\0 followed by 0 to 2 octal digits Interpret as an octal. For example, \044 is always interpreted as an octal value and means "$". Same behavior.
\ followed by a digit from 1 to 9, followed by no additional decimal digits, Interpret as a backreference. For example, \9 always means backreference 9, even if a ninth capturing group does not exist. If the capturing group does not exist, the regular expression parser throws an ArgumentException. If a single decimal digit capturing group exists, backreference to that digit. Otherwise, interpret the value as a literal.
\ followed by a digit from 1 to 9, followed by additional decimal digits Interpret the digits as a decimal value. If that capturing group exists, interpret the expression as a backreference. Otherwise, interpret the leading octal digits up to octal 377; that is, consider only the low 8 bits of the value. Interpret the remaining digits as literals. For example, in the expression \3000, if capturing group 300 exists, interpret as backreference 300; if capturing group 300 does not exist, interpret as octal 300 followed by 0. Interpret as a backreference by converting as many digits as possible to a decimal value that can refer to a capture. If no digits can be converted, interpret as an octal by using the leading octal digits up to octal 377; interpret the remaining digits as literals.

【讨论】:

感谢您的回答。正如我从您的回答中了解到的那样,如果我需要在 .Net 应用程序中使用带有 ECMAScript 风格的 Regex。 RegexOptions.ECMAScript 不是解决方案。 @itaiy .NET 使用自己的正则表达式引擎。它不能作为 ECMAScript 正则表达式引擎工作,也无法使其与其他一些正则表达式引擎一样工作。我刚刚解释了RegexOptions.ECMAScript 选项的工作原理。

以上是关于为啥运行带有 ECMAScript 风格支持的 .Net 正则表达式 \A的主要内容,如果未能解决你的问题,请参考以下文章

为啥休眠 5.3 不支持带有 infinispan 的事务缓存

ES6-21:编程风格ECMAScript规格

带有 wro4j 和 Google Closure 编译器的 ECMASCRIPT 5

默认情况下为啥没有设置线程化 perl(带有 usethreads)?

带有 Canvas 元素的 OpenType 风格集

使用 ECMAScript 6