正则表达式模式匹配顺序

Posted

技术标签:

【中文标题】正则表达式模式匹配顺序【英文标题】:Regular Expression Pattern Matching order 【发布时间】:2012-06-17 02:04:10 【问题描述】:

在我熟悉的所有语言的正则表达式引擎中,.* 表示法表示匹配零个或多个字符。考虑以下 javascript 代码:

var s = "baaabcccb";
var pattern = new RegExp("b.*b");
var match = pattern.exec(s);
if (match) alert(match);

这会输出baaabcccb

Python 也会发生同样的事情:

>>> import re
>>> s = "baaabcccb"
>>> m = re.search("b.*b", s)
>>> m.group(0)
'baaabcccb'

这两种语言都匹配"baaabcccb" 而不是简单的"baaab" 的原因是什么?我阅读模式b.*b 的方式是“找到一个以b 开头的子字符串,然后包含任意数量的其他字符,然后以b 结尾。” baaabbaaabcccb 都满足这个要求,但 Javascript 和 Python 都匹配后者。我原以为它会匹配baaab,仅仅是因为该子字符串满足要求并且首先出现。

那么为什么在这种情况下模式匹配baaabcccb?而且,是否有任何方法可以修改此行为(使用任何一种语言),以使其与 baaab 匹配?

【问题讨论】:

【参考方案1】:

因为 * 和 + 本质上是贪婪的(至少在 python 中,我不确定 js)。他们会尽量匹配。如果你想避免这个问题,你可以添加?在他们之后。

这里有一个很棒的教程,在贪婪与非贪婪部分: google python class

【讨论】:

【参考方案2】:

.* 是一个贪心匹配。 .*? 是非贪心版

【讨论】:

【参考方案3】:

您可以通过在* 之后添加? 来使正则表达式不贪婪,如下所示:b.*?b。然后它将匹配可能的最小字符串。默认情况下,正则表达式是贪婪的,并会尝试找到最长的匹配项。

【讨论】:

可能会添加默认情况下它是贪婪的,这意味着正则表达式将尝试匹配可能的最长字符串

以上是关于正则表达式模式匹配顺序的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式 3 -- 查找

以任何顺序匹配查询中的所有单词的正则表达式

Java的正则表达式

java正则表达式能不能不按顺序匹配?

perl学习正则表达式

正则表达式以任何顺序匹配字符串标记?