上一篇python正则匹配次数大家应该也发现了,除了?其他匹配次数规则都是尽可能多的匹配
那如果只想匹配1次怎么办呢,这就是正则中非贪婪模式的概念了
原理就是利用?与其他匹配次数规则进行组合
单个匹配规则:
* = {0,}表示匹配0-n次
+ = {1,}表示匹配1-n次
?= {0,1}表示匹配0-1次
三者可组合成非贪婪模式匹配次数解析:*? +? ??
简而言之:它们必须结合左右的子串进行匹配,左边正则必须非空,右边正则可以为空,中心思想就是在匹配到右边的正则之前尽可能少次匹配左边的正则
match是从头开始匹配,找到第一个符合条件的子字符串
?? =(reg1?)?reg2 = (reg1{0,1}){0,1}reg2
In [149]: re.match(r'w??d','123wer123') # 第一个d即数字之前,w只能匹配0-1次; 这里第一个d之前可匹配w 0次,返回第一个数字 Out[149]: <re.Match object; span=(0, 1), match='1'> In [150]: re.match(r'w??d','w123wer123') # 第一个d数字之前,w只能i匹配0-1次;这里第一个d之前w匹配到一次,返回一个字母+第一个数字 Out[150]: <re.Match object; span=(0, 2), match='w1'> In [151]: re.match(r'w??d','wx123wer123') # 第一个d数字之前,w只能匹配0-1次; 这里d前面匹配到w 2次,match失败,返回None In [152]: re.match(r'w??d','wxwer') #d至少匹配1次; 这里d没匹配到,所以最终match失败,返回None In [153]: re.match(r'w??','wxwer') # w只能匹配0-1次;这里选少的匹配0次 Out[153]: <re.Match object; span=(0, 0), match=''>
*? =(reg1*)?reg2 = (reg1{0,}){0,1}reg2
In [154]: re.match(r'w*?d','123wer123') # 第一个d前w只能匹配0-n次; 这里d前可匹配0次w, 返回第一个数字 Out[154]: <re.Match object; span=(0, 1), match='1'> In [155]: re.match(r'w*?d','wx123wer123') # 第一个d前w只能匹配0-n次;这里d前匹配2次w, 返回2个字母+一个数字 Out[155]: <re.Match object; span=(0, 3), match='wx1'> In [156]: re.match(r'w*?d','wxe') # d至少要匹配一次;这里d没有匹配项,最终匹配失败,返回None In [157]: re.match(r'w*?','wxe') # w只能匹配0-n次; 这里最少匹配0次 Out[157]: <re.Match object; span=(0, 0), match=''>
+? =(reg1+)?reg2 = (reg1{1,}){0,1}reg2
In [160]: re.match(r'w+?d','%123wer123') # 第一个d前w匹配只能匹配1-n次;这里第一个d前w只匹配到0次,最终match失败,返回None In [161]: re.match(r'w+?d','wsx123wer123') #第一个d前w只能匹配1-n次;这里第一个d前w最少匹配3次,最后返回三个字母+第一个数字 Out[161]: <re.Match object; span=(0, 4), match='wsx1'> In [162]: re.match(r'w+?d','wsxwer') # d必须至少匹配到一次;这里d匹配0次,最终匹配失败,返回None In [163]: re.match(r'w+?','wsxwer') # w只能匹配1-n次;这里w最少可匹配1次,即返回第一个字母 Out[163]: <re.Match object; span=(0, 1), match='w'>
In [165]: re.match(r'w+?w','wsxwer') # 第一个w之前,w只能出现1-n次;这里w最少可匹配到一次,所以返回w+第一个字母
Out[165]: <re.Match object; span=(0, 2), match='ws'>
In [27]: re.match(r'aw+?w','awwsxwer') # 第一个字母必须是a,在a和w之间,w可出现1-n次; 这里w最少可匹配到1次
Out[27]: <re.Match object; span=(0, 3), match='aww'>
#延伸思考32和33分别返回什么呢,答案见评论
In [32]: re.match(r'aw+?s','awawsxwer')
In [33]: re.match(r'(aw)+?s','awawsxwer')