正则表达式懒惰与贪婪的混淆

时间:2014-04-19 22:07:17

标签: regex

我对正则表达式和贪婪与懒惰有点困惑。它非常简单,感觉我错过了一些明显的东西。

我尽可能地简化了我的问题。请考虑以下字符串和正则表达式模式。

string:
aaxxxb

pattern:
(?<=a)(.*?)(?=b)

result:
axxx

what I expected:
xxx

这个结果是我期望使用的。*而不是。*?,我错过了什么?

显然,如果我使用。*?b同样的东西给了我aaxxxb。为什么是这样?不应该懒(比如。*?)尽可能少的字符?

2 个答案:

答案 0 :(得分:6)

你错过了一个正则表达式引擎从左到右,逐个位置工作,并在当前位置找到匹配后立即成功的事实。

在您的示例中,模式成功的第一个位置是第二个“a”。

懒惰只在右侧起作用。

如果您想获得“xxx”,更好的方法是使用否定的字符类[^ab]*而不是.*?

注意:与主题不完全相关,但很有必要:DFA正则表达式引擎会尝试在交替时获得最大的结果,NFA会为您提供第一个成功的结果。

答案 1 :(得分:2)

user1277327,您的模式的(?<=a)部分意味着&#34;前面有&#39; a&#39;&#34;。当正则表达式引擎启动你的字符串aaxxxb时,第一个&#34; a&#34;并不能完成那种外观的主张,但是第二个&#34; a&#34;确实。很好,但引擎可以匹配&#34; a&#34;?是的,你的。*中的点允许引擎匹配这个&#34; a&#34;。懒惰的修饰符?告诉点星只吃掉必要的字符,直到我们能够匹配接下来的字符。接下来要说的是前瞻性断言下一个角色是&#34; b&#34;。因此引擎会占用三个x字符。总比赛是axxx。

如果您发现贪婪/懒惰令人困惑,您可能需要查看the levels of regex greedlookarounds附带的啧啧也可能有所帮助。