正则表达式是一种描述复杂需求的字符串的表达式,入门看这里正则表达式 – 语法 | 菜鸟教程。
re模块为Python提供了正则表达式的相关操作,但是很多的方法因为相似度较大,因此经常造成一些混乱,在这里写一份笔记提供参考(方法里的可选参数就不讲了,因为一般也用不着)。
注:
re模块的正则表达式相关函数中都有一个flags参数,它代表了正则表达式的匹配标记,可以通过该标记来指定匹配时是否忽略大小写、是否进行多行匹配、是否显示调试信息等。其中一个常用可选参数,
flags=re.IGNORECASE
,表示匹配的时候忽略字符串大小写。如:print(re.match(r'The', 'The world is ...', flags=re.IGNORECASE))
1. match和fullmatch
1.1 match
match(pattern, string)
在字符串的开始进行匹配,如果匹配成功,返回正则表达式对象。
注意:如果在开头就不匹配,那就是不匹配,返回的是None,然而前面匹配到了后,后边多出来的字符就不管了
示例代码:
print(re.match(r'The', 'The world is ...'))
print(re.match(r'world', 'The world is ...'))
返回结果:
<re.Match object; span=(0, 3), match='The'>
None
很明显,world直接匹配不到了,因为world字符串不在开头
上面在书写正则表达式时使用了“原始字符串”的写法(在字符串前面加上了r),所谓“原始字符串”就是字符串中的每个字符都是它原始的意义,说得更直接一点就是字符串中没有转义字符。
因为正则表达式中有很多元字符和需要进行转义的地方,如果不使用原始字符串就需要将反斜杠写作\\,例如表示数字的\d得书写成\\d,这样不仅写起来不方便,阅读的时候也会很吃力。
1.2 fullmatch
fullmatch(pattern, string)
字符串从头匹配到尾,匹配成功才会返回正则表达式对象。
也就是说,后边多出来的字符串他也要管,发现没匹配到,直接返回None
示例代码:
print(re.fullmatch(r'The', 'The world is ...'))
# 下面的正则表达式的意思是,The后面跟着任意字符(.),且数量没有限制(*)
print(re.fullmatch(r'The.*', 'The world is ...'))
输出结果:
None
<re.Match object; span=(0, 16), match='The world is ...'>
第一行代码放在match那边就能匹配成功,在这儿却返回None,足以表明了fullmatch匹配更为严苛,需要从头到尾匹配。
2. search和findall
search和findall和上边的match和matchall的最重要差别是,search和findall不管头不管尾,只要在中间有地方匹配到了,就匹配成功了,看这方法名也可以看出匹配的严格程度较低。
示例代码:
# 下面正则表达式的意思是,先匹配一个下划线,然后匹配一个任意的(字母/数字/下划线)
print(re.search(r'_\w', 'The_world_is_...'))
print(re.findall(r'_\w', 'The_world_is_...'))
输出结果:
<re.Match object; span=(3, 5), match='_w'>
['_w', '_i']
输出的结果十分明显地能看出两大差别:
- search匹配成功后返回的是正则表达式对象,findall返回的是列表。
- search匹配到一个符合的以后,立即返回结果,而findall从头搜索到尾后再返回结果列表。
3. re.split和str.split
这里也要强调一下,re模块里的split方法
具有匹配正则表达式然后进行分割的功能,而字符串.split
方法,不能通过正则表达式分割字符串。
# 这里正则表达式的意思是,先匹配一个下划线后再匹配一个任意字符
print(re.split(r'_.', 'The_world_is_...'))
# 试图通过正则表达式来分割字符串
print('The_world_is_...'.split(r'_\w'))
# 使用普通的字符串来分割
print('The_world_is_...'.split(r'_'))
输出结果:
['The', 'orld', 's', '..']
['The_world_is_...']
['The', 'world', 'is', '...']