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

在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不同.

相关文章

正则替换html代码中img标签的src值在开发富文本信息在移动端...
正则表达式
AWK是一种处理文本文件的语言,是一个强大的文件分析工具。它...
正则表达式是特殊的字符序列,利用事先定义好的特定字符以及...
Python界一名小学生,热心分享编程学习。
收集整理每周优质开发者内容,包括、、等方面。每周五定期发...