.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 个捕获组的 (.)(.)(.)(.)(.)(.)(.)(.)(.)(.)
模式中,我们可以说存在歧义,因为 1
和 10
都可以引用现有的组,但是 .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>ArgumentException
:parsing '' - Unrecognized escape sequence
- 示例:
5
→ 抛出 ArgumentException
:parsing '5' - Unrecognized escape sequence
但是注意:
如果您使用 RegexOption ECMAScript
,行为会有所不同。
https://msdn.microsoft.com/en-us/library/yd1hzczs.aspx#ECMAScript
我正在学习.NET 正则表达式。 众所周知,八进制转义码(例如 \16)和 \number 反向引用之间存在歧义。 https://msdn.microsoft.com/en-us/library/thwdfzxy.aspx
我的问题是:
当正则表达式模式中未定义具有该编号的组时,</code> 或 <code>8
等正则表达式匹配什么?
它既不是有效的组号也不是有效的八进制代码。
但它是一个有效的正则表达式(甚至 848486
也是有效的)- Regex 构造函数不会抛出 ArgumentException 但我找不到任何匹配此类转义序列的输入字符串。
我只是好奇如何解释一个表达式。
当存在多种解析模式的可能性时,就会出现歧义。比如说,在具有 10 个捕获组的 (.)(.)(.)(.)(.)(.)(.)(.)(.)(.)
模式中,我们可以说存在歧义,因为 1
和 10
都可以引用现有的组,但是 .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>ArgumentException
:parsing '' - Unrecognized escape sequence
- 示例:
5
→ 抛出ArgumentException
:parsing '5' - Unrecognized escape sequence
- 示例:
但是注意:
如果您使用 RegexOption ECMAScript
,行为会有所不同。
https://msdn.microsoft.com/en-us/library/yd1hzczs.aspx#ECMAScript