正则表达式系列6:贪婪模式和非贪婪模式

标识符

先熟悉最基本的标识符

  1. . : 告诉引擎匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。

  2. ?: 告诉引擎匹配前导字符0次或一次。事实上是表示前导字符是可选的。

  3. +: 告诉引擎匹配前导字符1次或多次。

  4. *: 告诉引擎匹配前导字符0次或多次。

  5. {min, max}: 告诉引擎匹配前导字符min次到max次。min和max都是非负整数。如果有逗号而max被省略了,则表示max没有限制;如果逗号和max都被省略了,则表示重复min次。
    表示方式:{n},{n,},{n,m},
    因此 {0,} 和 * 一样,{1,} 和 + 的作用一样。


贪婪匹配:

默认情况下,? + * {min, max}都是贪婪的,也就是说,它会根据前导字符去匹配尽可能多的内容。
示例1:

import re
content = 'aacbacbc'
pattern = re.compile('a.*b')
result = re.search(pattern,content)
print(result.group())

结果:
aacbacb

例1中,匹配到第一个a后,开始匹配.*,由于是贪婪模式,
它会一直往后匹配,直到最后一个满足条件的b为止,因此匹配结果是aacbacb

示例2:

content = 'aacbacbc'
pattern = re.compile('ac.*b')
result = re.search(pattern,content)
print(result.group())

结果:
acbacb

例2中,第一个匹配的是a,然后再匹配下一个字符a时,和正则不匹配,因此匹配失败,index挪到1,接下来匹配成功了ac,继续往下匹配,由于是贪婪模式,尽可能多的去匹配结果,直到最后一个符合要求的b为止,因此匹配结果是acbacb

非贪婪匹配

正则表达式去匹配时,会尽量多的匹配符合条件的内容。
+,?,*,{n},{n,},{n,m}
匹配时,如果遇到上述标识符,代表是贪婪匹配,会尽可能多的去匹配内容。

示例1:

content = 'aacbacbc'
pattern = re.compile('a.*?b')
result = re.search(pattern,content)
print(result.group())

结果:
aacb

上例中,匹配到第一个a后,开始匹配.*?,由于是非贪婪模式,它在匹配到了第一个b后,就匹配成功了,因此匹配结果是aacb
为什么是aacb而不是acb呢? 因为前面有提到过一个正在匹配的优先规则: 最先开始的匹配拥有最高的优先权 第一个a匹配到了,只要之后没有发生匹配失败的情况,它就会一直匹配下去,直到匹配成功。

示例2:

content = 'aacbacdbc'
pattern = re.compile('ac.*?b')
result = re.findall(pattern,content)
print(result)

结果:
[‘acb’, ‘acdb’]

上例中没用re.search,因为它返回第一个成功的匹配结果,我们用re.findall,找出所有符合匹配的结果。

示例3:

content = 'aacbacbc'
pattern1 = re.compile('a.*?')
result1 = re.search(pattern1,content)
print(result1.group())
pattern2 = re.compile('a.*')
result2 = re.search(pattern2,content)
print(result2.group())

结果:
a
aacbacbc

这一个例子则是对非贪婪匹配示例1的补充,可以发现,当后面没有b时,由于是非贪婪模式,匹配到第一个a就直接匹配成功了 而后面一个贪婪模式的匹配则是会匹配所有。

参考资料
正则表达式 - 贪婪与非贪婪(惰性)
正则表达式系列:贪婪与非贪婪模式

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值