微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

正则表达式 – 带有命名子模式的正则表达式看不到最佳匹配

在reg exp中使用已定义的子模式时,它不会选择最佳匹配,而是在第一次匹配时停止.我忘记了一些国旗吗?

正则表达式:(α< min> [0-9] | [1-5] [0-9]):(α&分钟);
测试字符串:47:24;.

表达式不匹配:

但是字符串47:2;匹配正确:

.

如果我将’或’条件改为[1-5] [0-9] | [0-9],则reg exp(?< minutes> [1-5] [0-9] | [0-9]) :;(&安培;分钟?)工作得很好.有没有其他方法可以使字符串’47:24;’匹配而不反转’或’条件?

解决方法

使用PCRE,递归组是原子的(参见本 article).这就是正则表达式引擎无法回溯(?& minutes)的原因.

在42:24;中,24中的2与第一个分支[0-9]匹配(自第一次获胜以来),但是当模式失败时,因为字符串中有4而不是;,正则表达式引擎可以在(?& minutes)子模式中回溯以测试第二个分支[1-5] [0-9]. (你可以看看debugger)

解决方案:不要对如此小的子模式使用递归,它是无用的,没有意义(特别是如果你使用捕获组的名称).写点像:

(?<minutes>[1-5]?[0-9]):(?<seconds>[1-5]?[0-9]);

或者为什么不:

(?(DEFINE)(?<sex>[1-5]?[0-9]) for "sexagesimal",not for what you think)
(?<minutes>(?&sex)):(?<seconds>(?&sex));

看起来多余,但有意义,如果你想提取分钟和秒钟(或者根本不使用组),这是有用的.毕竟,如果你使用命名捕获,你的目标不是写出世界上最短的模式.

如果你无法避免交替:

>你可以把最长的分支放在第一位:[1-5] [0-9] | [0-9]按照卢卡斯的建议.
>你也可以使用互斥的分支:[1-5] [0-9]?| [06-9],[06-9] | [1-5] [0-9]? (在这种情况下,订单无关紧要)

请注意,递归组的这种行为特别适用于PCRE,它与Perl或Ruby不同.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐