重用分支重置组并不匹配所有替代方案
Reusing branch reset group doesn't match all the alternatives
我正在尝试使用下面的 RegEx 验证 IPv4 地址
^((?|([0-9][0-9]?)|(1[0-9][0-9])|(2[0-5][0-5]))\.){3}(?2)$
在大多数情况下,正则表达式在 IP 地址的第三个八位字节之前工作正常。但有时在最后一个八位位组中,它只匹配 Branch Reset Group 中的第一个备选组,而完全忽略其他交替组。我知道分支重置组中的所有替代方案都指的是同一个捕获组。我尝试了重用 中描述的捕获组的建议。它部分起作用了。
原因是(?2)
regex subroutine recurses the first capturing group pattern with the ID 2、([0-9][0-9]?)
。如果匹配失败($
要求紧跟其后的字符串结尾),则开始回溯,最终匹配失败。
递归一组模式的正确方法是避免使用 branch reset group 并将所有备选方案捕获到将被递归的 单个 捕获组中:
^(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?1)$
// |____________ Group 1 _______________| \_ Regex subroutine
参见regex demo。
注意八位位组模式有点不同,它取自 How to Find or Validate an IP Address。您的八位字节模式是错误的,因为 2[0-5][0-5]
与 200
和 255
之间以 6
、7
、8
和 [= 结尾的数字不匹配20=].
此页面上有关于此行为的解释:
https://www.pcre.org/original/doc/html/pcrepattern.html#SEC15
文档指出:
a subroutine call to a numbered subpattern always refers to the first
one in the pattern with the given number.
使用该页面上的示例:
(?|(abc)|(def))(?1)
Inside a (?| group, parentheses are numbered as usual, but the number
is reset at the start of each branch.
数字将如下所示
(?|(abc)|(def))
1 1
这将匹配
abcabc
defabc
abcabc
但是不匹配
defdef
它不匹配 defdef
因为该模式将匹配第一个 def
,但随后的 (?1)
将仅匹配第一个编号的子模式 (abc)
看到一个regex demo.
我正在尝试使用下面的 RegEx 验证 IPv4 地址
^((?|([0-9][0-9]?)|(1[0-9][0-9])|(2[0-5][0-5]))\.){3}(?2)$
在大多数情况下,正则表达式在 IP 地址的第三个八位字节之前工作正常。但有时在最后一个八位位组中,它只匹配 Branch Reset Group 中的第一个备选组,而完全忽略其他交替组。我知道分支重置组中的所有替代方案都指的是同一个捕获组。我尝试了重用
原因是(?2)
regex subroutine recurses the first capturing group pattern with the ID 2、([0-9][0-9]?)
。如果匹配失败($
要求紧跟其后的字符串结尾),则开始回溯,最终匹配失败。
递归一组模式的正确方法是避免使用 branch reset group 并将所有备选方案捕获到将被递归的 单个 捕获组中:
^(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?1)$
// |____________ Group 1 _______________| \_ Regex subroutine
参见regex demo。
注意八位位组模式有点不同,它取自 How to Find or Validate an IP Address。您的八位字节模式是错误的,因为 2[0-5][0-5]
与 200
和 255
之间以 6
、7
、8
和 [= 结尾的数字不匹配20=].
此页面上有关于此行为的解释:
https://www.pcre.org/original/doc/html/pcrepattern.html#SEC15
文档指出:
a subroutine call to a numbered subpattern always refers to the first one in the pattern with the given number.
使用该页面上的示例:
(?|(abc)|(def))(?1)
Inside a (?| group, parentheses are numbered as usual, but the number is reset at the start of each branch.
数字将如下所示
(?|(abc)|(def))
1 1
这将匹配
abcabc
defabc
abcabc
但是不匹配
defdef
它不匹配 defdef
因为该模式将匹配第一个 def
,但随后的 (?1)
将仅匹配第一个编号的子模式 (abc)
看到一个regex demo.