演示示例:
#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.第一个查找字符是 " ,正则引擎在第三个位置匹配到了它:
2.之后,引擎尝试匹配正则的剩余部分,第二个字符是 .(点) ,它代表任意字符。引擎匹配到了w:
3.*
代表任意字符重复一次到多次,因此正则引擎匹配到所有字符
4.当文本结束后,点的匹配停止了,但仍然有剩余的正则"
需要匹配,因此正则引擎开始倒过来回溯,换句话说,就是一个字符一个字符缩减匹配。
当匹配缩减后,它开始尝试匹配剩余的正则,但"没有匹配上字符e。
5.因此正则继续缩减.所重复的字符,继续尝试。
边缩减一位,边验证匹配一位
6.正则引擎回溯,一次一次缩减.重复的字符个数,直到剩余的正则都匹配上:
现在"终于匹配上了。
所以说,在贪婪模式下,正则引擎尽可能多的匹配字符
非贪婪模式:
非贪婪模式和贪婪模式相反,可通过在代表数量的标识符后放置?来开启非贪婪模式,如?、+?甚至是??。
示例:
#python 3.7
import re str = 'a "witch" and her "broom" is one'
a = re.findall(r'"(.*?)"',str)
print(a)
运行结果:
['witch', 'broom']
1.第一步和上面类似,引号"被匹配上
2.第二步也一样, '.'被匹配上
3.下面是二者的重要区别。 正则引擎尝试用最小可能的重复次数来进行匹配,因此在.
(点)匹配了w后,它立即尝试"
的匹配
可惜没有匹配上,因为i!="
4. .(点)重复更多的字符,再进行尝试
又没匹配上,继续~~
5.下面终于匹配上了
6.因为findall匹配全部字符串所以继续往后进行
同样的道理
所以说,在非贪婪模式下,正则引擎尽可能少的重复匹配字符。
贪婪模式与非贪婪模式的正则引擎匹配的区别在于:
贪婪模式:.(点)先全部进行匹配完,如果还有没有匹配的正则字符,则用未匹配的进行回溯。
非贪婪模式:.匹配一个任意字符,下一个接着匹配.后的正则字符 ,如果下一个匹配失败,继续用.匹配,然后在用.后正则字符匹配,直到.后的正则字符匹配成功。