-
正则表达式贪婪和非贪婪
什么是正则表达式的贪婪与非贪婪匹配
如:String str="abcaxc";
Patter p="ab*c";
贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcaxc(ab*c)。
非贪婪匹配:就是匹配到结果就好,就少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc(ab*c)。
下面通过实例代码看下正则表达式的贪婪模式与非贪婪模式,具体内容如下所示:
贪婪模式:能匹配的最大部分
1 2 3 4 |
s = "This is a number 234-235-22-4223" r = re.match(r "(.+)(\d+-\d+-\d+-\d+" ,s) r.groups() ( "This is a number 23" , "4-235-22-4223" ) |
贪婪模式就是“.+”中的+会一直查找到最后一个符合条件的字符,所以上述代码中最前面的两个数字在提取数字是没有被提取到
非贪婪模式:匹配越少越好
1 2 3 4 |
s = "This is a number 234-235-22-4223" r = re.match(r "(.+?)(\d+-\d+-\d+-\d+" ,s) r.groups() ( "This is a number " , "234-235-22-4223" ) |
非贪婪模式就是在“.+?"会匹配到第一个符合条件的字符就停止
比如假定匹配字符串和正则表达式为:
>>> match_str = 'abcdefc' #匹配字符串
贪婪匹配:
>>> pattern = r'ab.*c'
>>> re.match(pattern,match_str)
<_sre.SRE_Match object; span=(0, 7), match='abcdefc'>
正则表达式一般趋向于最大长度匹配,总是尝试匹配尽可能多的字符,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcdefc。当出现c时,它还是继续向后找,又找到c,它就把cdef当做是(.*)的匹配
非贪婪匹配:
>>> pattern = r'ab.*?c' #非贪婪匹配
>>> re.match(pattern,match_str)
<_sre.SRE_Match object; span=(0, 3), match='abc'>
非贪婪匹配就是匹配到结果就好,总是尝试匹配尽可能少的字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc。当它遇见c后,它就停止查找,此时把空字符作为(.*)的匹配。
那么贪婪与非贪婪怎么区分呢?
re模块默认是贪婪模式;在量词后面直接加上一个问号?就是非贪婪模式。
我们熟知的量词有:
* 任意多个
+ 至少一个
? 0或1个
{m,n} m到n个
在上一节中的去除HTML中的标签时,我们使用r'<.+>'去匹配得到的却是一堆'\n',我们来看看原因。拿其中的一行来看,为什么输出'\n':
<p><br/></p>
分析:sub函数先做匹配操作,再做替换操作。在匹配操作时,首先匹配 <(左尖括号),<p>的<就已经匹配到,当匹配到<p>的>时,匹配未结束,它继续往后匹配。当匹配到<br/>的>时,仍然未结束,贪婪的向后继续匹配,直到匹配到</p>的>,再继续去匹配,字符串后面有个‘\n',结束匹配,它就把 p><br/></p 这些内容都当做 .+ 来处理。因此匹配到这一行内容除了'\n',并进行替换操作,替换为空字符'',因此输出'\n'。因此,在 .+ 后面加上?表示非贪婪模式,当碰到<p>的 > 就停止此次匹配。
>>> re.sub(r'<.+?>','',s)