PCRE 正则表达式在移动到子例程时表现不同
PCRE regex behaves differently when moved to subroutine
使用 PCRE v8.42,我试图将一个正则表达式抽象为一个命名的子例程,但是当它在一个子例程中时,它的行为似乎有所不同。
这输出 10/
:
echo '10/' | pcregrep '(?:0?[1-9]|1[0-2])\/'
这没有输出:
echo '10/' | pcregrep '(?(DEFINE)(?<MONTHNUM>(?:0?[1-9]|1[0-2])))(?&MONTHNUM)\/'
这两个正则表达式不等价吗?
在 PCRE2 prior to 10.30, all subroutine calls are always treated as atomic groups. Your (?(DEFINE)(?<MONTHNUM>(?:0?[1-9]|1[0-2])))(?&MONTHNUM)\/
regex is actually equal to (?>0?[1-9]|1[0-2])\/
. See this regex demo 版本中,10/
与预期不匹配。
没有匹配,因为 0?[1-9]
与 10/
中的 1
匹配,并且由于不允许回溯,因此未测试(“输入”)第二个备选方案,并且整场比赛失败,因为 1
.
之后没有 /
您需要确保较长的备选方案排在第一位:
(?(DEFINE)(?<MONTHNUM>(?:1[0-2]|0?[1-9])))(?&MONTHNUM)/
见regex demo。请注意,在 pcregrep
模式中,您不需要转义 /
.
或者,您可以使用 PCRE2 v10.30 或更新版本。
使用 PCRE v8.42,我试图将一个正则表达式抽象为一个命名的子例程,但是当它在一个子例程中时,它的行为似乎有所不同。
这输出 10/
:
echo '10/' | pcregrep '(?:0?[1-9]|1[0-2])\/'
这没有输出:
echo '10/' | pcregrep '(?(DEFINE)(?<MONTHNUM>(?:0?[1-9]|1[0-2])))(?&MONTHNUM)\/'
这两个正则表达式不等价吗?
在 PCRE2 prior to 10.30, all subroutine calls are always treated as atomic groups. Your (?(DEFINE)(?<MONTHNUM>(?:0?[1-9]|1[0-2])))(?&MONTHNUM)\/
regex is actually equal to (?>0?[1-9]|1[0-2])\/
. See this regex demo 版本中,10/
与预期不匹配。
没有匹配,因为 0?[1-9]
与 10/
中的 1
匹配,并且由于不允许回溯,因此未测试(“输入”)第二个备选方案,并且整场比赛失败,因为 1
.
/
您需要确保较长的备选方案排在第一位:
(?(DEFINE)(?<MONTHNUM>(?:1[0-2]|0?[1-9])))(?&MONTHNUM)/
见regex demo。请注意,在 pcregrep
模式中,您不需要转义 /
.
或者,您可以使用 PCRE2 v10.30 或更新版本。