演示示例:

#python 3.7
import re
str = ‘a "witch" and her "broom" is one’
a = re.findall(r'"(.*)"',str)
print(a)

贪婪模式(默认):

#python 3.7
import re
str = ‘a "witch" and her "broom" is one’
a = re.findall(r'"(.*)"',str)
print(a)
运行结果:
['witch" and her "broom']

在这里为了直观,我们模拟一下正则引擎

1.第一个查找字符是 " ,正则引擎在第三个位置匹配到了它:

对正则表达式贪婪模式与非贪婪模式的理解-D-R0s1博客

2.之后,引擎尝试匹配正则的剩余部分,第二个字符是 .(点) ,它代表任意字符。引擎匹配到了w:

对正则表达式贪婪模式与非贪婪模式的理解-D-R0s1博客

3.*代表任意字符重复一次到多次,因此正则引擎匹配到所有字符

对正则表达式贪婪模式与非贪婪模式的理解-D-R0s1博客

4.当文本结束后,点的匹配停止了,但仍然有剩余的正则"需要匹配,因此正则引擎开始倒过来回溯,换句话说,就是一个字符一个字符缩减匹配。

对正则表达式贪婪模式与非贪婪模式的理解-D-R0s1博客

当匹配缩减后,它开始尝试匹配剩余的正则,但"没有匹配上字符e。

5.因此正则继续缩减.所重复的字符,继续尝试。

对正则表达式贪婪模式与非贪婪模式的理解-D-R0s1博客

边缩减一位,边验证匹配一位

6.正则引擎回溯,一次一次缩减.重复的字符个数,直到剩余的正则都匹配上:

对正则表达式贪婪模式与非贪婪模式的理解-D-R0s1博客

现在"终于匹配上了。
所以说,在贪婪模式下,正则引擎尽可能多的匹配字符

非贪婪模式

非贪婪模式和贪婪模式相反,可通过在代表数量的标识符后放置?来开启非贪婪模式,如?、+?甚至是??。
示例:

#python 3.7 
import re str = 'a "witch" and her "broom" is one' 
a = re.findall(r'"(.*?)"',str) 
print(a) 

运行结果: 
['witch', 'broom']

1.第一步和上面类似,引号"被匹配上

对正则表达式贪婪模式与非贪婪模式的理解-D-R0s1博客

2.第二步也一样, '.'被匹配上

对正则表达式贪婪模式与非贪婪模式的理解-D-R0s1博客

3.下面是二者的重要区别。 正则引擎尝试用最小可能的重复次数来进行匹配,因此在.(点)匹配了w后,它立即尝试"的匹配

对正则表达式贪婪模式与非贪婪模式的理解-D-R0s1博客

可惜没有匹配上,因为i!="

4. .(点)重复更多的字符,再进行尝试

对正则表达式贪婪模式与非贪婪模式的理解-D-R0s1博客

又没匹配上,继续~~

5.下面终于匹配上了

对正则表达式贪婪模式与非贪婪模式的理解-D-R0s1博客

6.因为findall匹配全部字符串所以继续往后进行

对正则表达式贪婪模式与非贪婪模式的理解-D-R0s1博客

同样的道理
所以说,在非贪婪模式下,正则引擎尽可能少的重复匹配字符。

贪婪模式与非贪婪模式的正则引擎匹配的区别在于:

贪婪模式:.(点)先全部进行匹配完,如果还有没有匹配的正则字符,则用未匹配的进行回溯
非贪婪模式:.匹配一个任意字符,下一个接着匹配.后的正则字符 ,如果下一个匹配失败,继续用.匹配,然后在用.后正则字符匹配,直到.后的正则字符匹配成功。