.NET 正则表达式“\19abc”匹配什么?

What does the .NET Regex "\19abc" match?

我正在学习.NET 正则表达式。 众所周知,八进制转义码(例如 \16)和 \number 反向引用之间存在歧义。 https://msdn.microsoft.com/en-us/library/thwdfzxy.aspx

我的问题是: 当正则表达式模式中未定义具有该编号的组时,</code> 或 <code>8 等正则表达式匹配什么?

它既不是有效的组号也不是有效的八进制代码。 但它是一个有效的正则表达式(甚至 848486 也是有效的)- Regex 构造函数不会抛出 ArgumentException 但我找不到任何匹配此类转义序列的输入字符串。

我只是好奇如何解释一个表达式。

当存在多种解析模式的可能性时,就会出现歧义。比如说,在具有 10 个捕获组的 (.)(.)(.)(.)(.)(.)(.)(.)(.)(.) 模式中,我们可以说存在歧义,因为 110 都可以引用现有的组,但是 .NET 正则表达式引擎将这种歧义解决为最大可能的值,并且此正则表达式 won't match 12345678901, but will match 12345678900. To get rid of the ambiguity, you need to use \k<ID> backreferences. (.)(.)(.)(.)(.)(.)(.)(.)(.)(.)\k<1>0 会匹配 123456789010,但不会匹配 123456789000.

848486 模式匹配八进制 14 字符,然后是 848486 序列,因为这里没有歧义。

848486 模式将匹配八进制 1 个字符,然后是 8848486 个字符的序列。见 this C# demo:

var s = Regex.Match("\u00018848486", @"848486");
if (s.Success) Console.WriteLine(s.Value); // => 8848486

我还建议使用 Ultrapico Expresso(无从属关系)调试 .NET 正则表达式,请参见屏幕截图:

至于</code>和<code>8

此外,当您对缺少的组使用反向引用时,如 \k<1>8848486,您 will get a System.ArgumentException: parsing '\k<1>8848486' - Reference to undefined group number N exception. When you have 8 or 9 after \, as in 48486, you will get System.ArgumentException: parsing '48486' - Unrecognized escape sequence N exception.

Wiktor Stribiżew 是对的。

这是我对 .NET 正则表达式引擎 默认(规范) 行为的总结

  • 表达式 </code> 到 <code>(后面没有更多数字)始终被解释为反向引用,而不是八进制代码。 (https://msdn.microsoft.com/en-us/library/thwdfzxy.aspx)
  • 如果在正则表达式模式中没有定义此指定数字的捕获组,则使用 </code> 到 <code> 将导致 ArgumentException。 (parsing '' - Reference to undefined group number)
  • 如果它是一个多位表达式,Regex 引擎首先尝试匹配十进制数字序列(在 \ 之后)作为对该编号组(捕获组)的反向引用。
  • 如果在正则表达式模式中没有定义具有该数字的捕获组,则引擎会尝试将数字序列解释为八进制代码:
  • 如果序列中有 3 个或更多八进制数字 (0...7),则引擎会将代码的字符与前 3 个数字匹配。后面的任何其他数字都将作为文字进行匹配。
    • 示例:0 → 匹配 octal 040
    • 示例:[=18=]40 → 匹配 octal 004,然后 0
    • 示例:4 → 匹配 octal 134
    • 示例:4567 → 匹配 octal 134,然后 5,然后 6,然后 7
  • 否则,如果有 2 个八进制数字 (0...7),则引擎匹配 具有这 2 位数字的代码字符。后面的任何其他数字都将作为文字进行匹配。
    • 示例:9 → 匹配 octal 04,然后 9
    • 示例:</code> → 匹配 <code>octal 13
    • 示例:8567 → 匹配 octal 13,然后 8,然后 5,然后 6,然后 7
  • 否则,如果只有 1 个八进制数字 (0...7),则引擎会将代码的字符与这 1 个数字匹配。后面的任何其他数字都将作为文字进行匹配。
    • 示例:[=39=] → 匹配 octal 0
    • 示例:</code> → 匹配 <code>octal 0,然后 8
    • 示例:</code> → 匹配 <code>octal 7
    • 示例:456 → 匹配 octal 1,然后 9,然后 4,然后 5,然后 6
  • 否则,如果反斜杠后的八进制数字为零,则引擎将抛出 ArgumentException。
    • 示例:</code> → 抛出 <code>ArgumentExceptionparsing '' - Unrecognized escape sequence
    • 示例:5 → 抛出 ArgumentExceptionparsing '5' - Unrecognized escape sequence

但是注意: 如果您使用 RegexOption ECMAScript,行为会有所不同。 https://msdn.microsoft.com/en-us/library/yd1hzczs.aspx#ECMAScript