为什么懒惰的正则表达式会捕获额外的单词?

时间:2016-06-26 02:02:50

标签: python regex

我正在使用以下懒惰的正则表达式来找到" ="之前和之后的单词。我不确定为什么会捕获额外的单词

r'\s+(.*?)\s+\=\s+(.*?)\s+'

文字格式为

my name = jil
part = #2

所以我想捕获name = jil

我在这里做错了什么,或者我可以用不同的方式做错。

注意:" ="之前和之后我们可以有特殊字符

1 个答案:

答案 0 :(得分:2)

您正在寻找: (\S+)\s*\=\s*(\S+)

\S匹配非空格,并允许捕获组中的./\#@&等。

\w仅匹配单词字符,因此匹配等于之前的最后一个单词和之后的第一个单词,如果您将\s+更改为\s*,则在=之间有或没有空格

为什么它不起作用是因为它从左到右解析:当它发现任何数量的空白\s+时,它开始吸入所有字符.*?直到找到" ="。所以它会在" ="之前匹配任何空白字符之后的整行。

懒惰的评价不会回过头来找到它能够达到的最小值,直到它达到第一个完整的匹配并停止:

dog dog dog dog = cat cat cat cat

懒惰捕获\s+(.*?)\s+= 提供:我们dog dog dog,因为它是第一次匹配:从第一只狗后的" "开始到第一只狗找到的第一只" ="结束。第二组完成了您的期望,因为它没有额外的要求,它以等号的空格结束。

=之后,懒惰将其限制为仅第一个单词,因为这是它获得匹配的第一个点。一个贪婪的版本会继续吸吮字符并找到以\s+结尾的最长字符串。

tl; dr :延迟评估不会返回找到最小的匹配,它会在从左到右解析时抓住第一个匹配。 d+?og将完全匹配ddddddog,因为它需要吞噬所有其他d以匹配第一个dog并且 lazy 回去看看是否真的需要吃掉所有这些额外的角色。