如何解决PCRE 正则表达式在移动到子程序时表现不同
使用 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 版本中,所有子程序调用都是 always treated 作为 atomic groups。您的 (?(DEFINE)(?<MONTHNUM>(?:0?[1-9]|1[0-2])))(?&MONTHNUM)\/
正则表达式实际上等于 (?>0?[1-9]|1[0-2])\/
。请参阅 this regex demo,其中 10/
与预期不匹配。
没有匹配,因为 0?[1-9]
匹配了 1
中的 10/
并且由于不允许回溯,第二个选择没有被测试(“输入”),并且整个匹配失败,因为 /
之后没有 1
。
您需要确保较长的替代方案优先:
(?(DEFINE)(?<MONTHNUM>(?:1[0-2]|0?[1-9])))(?&MONTHNUM)/
参见regex demo。请注意,在 pcregrep
模式中,您不需要转义 /
。
或者,您可以使用 PCRE2 v10.30 或更新版本。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。