文章目录
- 专栏导读
- 1、贪婪与非贪婪
- 2、转义匹配
专栏导读
✍ 作者简介:i阿极,CSDN 数据分析领域优质创作者,专注于分享python数据分析领域知识。
✍ 本文录入于《python网络爬虫实战教学》,本专栏针对大学生、初级数据分析工程师精心打造,对python基础知识点逐一击破,不断学习,提升自我。
✍ 订阅后,可以阅读《python网络爬虫实战教学》中全部文章内容,包含python基础语法、数据结构和文件操作,科学计算,实现文件内容操作,实现数据可视化等等。
✍ 其他专栏:《数据分析案例》 ,《机器学习案例》😊😊😊如果觉得文章不错或能帮助到你学习,可以点赞👍收藏📁评论📒+关注哦!👍👍👍
1、贪婪与非贪婪
使用通用匹配.*匹配到的内容有时候并不是我们想要的结果。
看下面的例子:
import re
content = "Hello 1234567 World_This is a Regex Demo"
result = re.match('^He.*(\d+).*Demo$', content)
print(result)
print(result.group(1))
这里我们依然想获取目标字符串中间的数字,所以正则表达式中间写的依然是(\d+)。而数字两侧由于内容比较杂乱,所以想省略来写,于是都写成.* 最后,组成^He.*(\d+).*Demo$,看样子没什么问题。
可我们看下运行结果:
<re.Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'>
7
奇怪的事情发生了,只得到了7这个数字,这是怎么回事?
这里涉及贪婪匹配和非贪婪匹配的问题。在贪婪匹配下,.*会匹配尽可能多的字符。正则表达式中。*后面是\d+,也就是至少一个数字,而且没有指定具体几个数字,因此,.*会匹配尽可能多的字符,这里就把123456都匹配了,只给\d+留下一个可满足条件的数字7,因此最后得到的内容就只有数字7。
但这很明显会给我们带来很大的不便。有时候,匹配结果会莫名其妙少一部分内容。其实,这里只需要使用非贪婪匹配就好了。非贪婪匹配的写法是 .*?,比通用匹配多了一个?,那么它可以起到怎样的效果?我们再用实例看一下:
import re
content = 'Hello 1234567 World_This is a Regex Demo'
result = re.match(r'^He.*?(\d+).*Demo$', content)
print(result)
print(result.group(1))
这里我们只是将第一个.* 改成了.*?,贪婪匹配就转变为了非贪婪匹配。结果如下:
<re.Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'>
1234567
此时便可以成功获取1234567了。原因可想而知,贪婪匹配是匹配尽可能多的字符,非贪婪匹配就是匹配尽可能少的字符。当.* ?匹配到Hello后面的空白字符时,再往后的字符就是数字了,而\d+恰好可以匹配,于是这里.?就不再进行匹配了,而是交给\d+去匹配。最后.?匹配了尽可能少的字符,Λd+的结果就是1234567。
所以说,在做匹配的时候,字符串中间尽量使用非贪婪匹配,也就是用.* ?代替.,以免出现匹配结果缺失的情况。但这里需要注意,如果匹配的结果在字符串结尾 . ?有可能匹配不到任何内容了,因为它会匹配尽可能少的字符。例如:
import re
content = "http://weibo.com/comment/kEraCN"
result1 = re.match("http.*?comment/(.*?)", content)
result2 = re.match("http.*?comment/(.*)", content)
print('result1',result1.group(1))
print('result2',result2.group(1))
运行结果如下:
result1
result2 kEraCN
可以观察到, .*?没有匹配到任何结果,而.*则是尽量多匹配内容,成功得到了匹配结果。
2、转义匹配
我们知道正则表达式定义了许多匹配模式,如.用于匹配除换行符以外的任意字符。但如果目标字符串里面就包含.这个字符,那该怎么办呢?
这时需要用到转义匹配,实例如下:
import re
content = '(百度)www.baidu.com'
result = re.match(r'\(百度\)www\.baidu\.com', content)
print(result)
当在目标字符串中遇到用作正则匹配模式的特殊字符时,在此字符前面加反斜线\转义一下即可
例如.就可以用来匹配.,运行结果如下:
<re.Match object; span=(0, 17), match='(百度)www.baidu.com'>
可以看到,这里成功匹配到了原字符串。
📢文章下方有交流学习区!一起学习进步!💪💪💪
📢首发CSDN博客,创作不易,如果觉得文章不错,可以点赞👍收藏📁评论📒
📢你的支持和鼓励是我创作的动力❗❗❗