不懂懒惰的正则表达式

时间:2014-12-07 15:04:04

标签: python regex lazy-evaluation

假设我们有一个字符串1abcd1efg1hjk1lmn1,并希望找到1 - s之间的内容。我们做的是

re.findall('1.*?1','1abcd1efg1hjk1lmn1')

获得两个结果

['1abcd1', '1hjk1']
好吧,我明白了。但是,如果我们这样做

re.findall('1.*?1hj','1abcd1efg1hjk1lmn1')

为什么它会在1 s而不是一个之间抓住两个间隔?为什么我们会['1abcd1efg1hj']而不是['1efg1hj']?这不是懒惰应该做的吗?

2 个答案:

答案 0 :(得分:5)

正则表达式总是尝试从左到右匹配输入字符串。考虑一下你的'1.*?1hj'正则表达式。你的正则表达式中的1与第一个.*?匹配,并且以下1hj非贪婪地匹配['1abcd1efg1hj']子字符串以外的所有字符。因此,您获得了['1efg1hj']而不是['1efg1hj']

要将1[^1]*1hj作为输出,您需要使用否定类作为>>> s = "1abcd1efg1hjk1lmn1" >>> re.findall(r'1.*?1hj', s) ['1abcd1efg1hj'] >>> re.findall(r'1[^1]*1hj', s) ['1efg1hj']

{{1}}

答案 1 :(得分:0)

['1abcd1efg1hj']

你得到这个因为这满足你的正则表达式。1.*?1hj本质上意味着从1开始然后懒惰地移动,直到找到1后跟hj。{{1}如果1之后不匹配,但ef会消耗所有内容。你不会得到.因为第一场比赛已经消耗了字符串。请使用前瞻查看两者都满足条件。参见演示。

前瞻不消耗字符串,因此您同时获得匹配,

https://regex101.com/r/aQ3zJ3/5