2.4 字符串匹配和搜索
问题
你想匹配或者搜索特定模式的文本
解决方案
果你想匹配的是字面字符串,那么你通常只需要调用基本字符串方法就行, 比如 str.find()
, str.endswith()
, str.startswith()
或者类似的方法。
对于复杂的匹配需要使用正则表达式和 re
模块。
如果你想使用同一个模式去做多次匹配,你应该先将模式字符串预编译为模式对象。
match()
总是从字符串开始去匹配,如果你想查找字符串任意部分的模式出现位置, 使用 findall()
方法去代替。
在定义正则式的时候,通常会利用括号去捕获分组。
捕获分组可以使得后面的处理更加简单,因为可以分别将每个组的内容提取出来。比如:
>>> datepat = re.compile(r'(\d+)/(\d+)/(\d+)')
>>> m = datepat.match('11/27/2012')
>>> m
<_sre.SRE_Match object at 0x1005d2750>
>>> # Extract the contents of each group
>>> m.group(0)
'11/27/2012'
>>> m.group(1)
'11'
>>> m.group(2)
'27'
>>> m.group(3)
'2012'
>>> m.groups()
('11', '27', '2012')
>>> month, day, year = m.groups()
findall()
方法会搜索文本并以列表形式返回所有的匹配。 如果你想以迭代方式返回匹配,可以使用 finditer()
方法来代替,比如:
>>> for m in datepat.finditer(text):
... print(m.groups())
...
('11', '27', '2012')
('3', '13', '2013')
讨论
需要注意的是 match()
方法仅仅检查字符串的开始部分。它的匹配结果有可能并不是你期望的那样。比如:
>>> m = datepat.match('11/27/2012abcdef')
>>> m
<_sre.SRE_Match object at 0x1005d27e8>
>>> m.group()
'11/27/2012'
如果你想精确匹配,确保你的正则表达式以$结尾。如果你仅仅是做一次简单的文本匹配/搜索操作的话,可以略过编译部分,直接使用 re
模块级别的函数。
如果你打算做大量的匹配和搜索操作的话,最好先编译正则表达式,然后再重复使用它。 模块级别的函数会将最近编译过的模式缓存起来,因此并不会消耗太多的性能, 但是如果使用预编译模式的话,你将会减少查找和一些额外的处理损耗。
Last updated
Was this helpful?