Re 模块为我们提供的函数,简单来说可以分为以下三大类:
- “匹配” 类函数;
- “修改” 类函数;
下面,我们就来一一详细介绍~
一. 匹配类函数
findall
findall
函数是 re 模块中最简单的匹配函数,也是我们最常用的匹配函数。findall
用于在文本中查找与模式相匹配的字符串,并将所有匹配的字符串以列表i的形式返回。
注:无论最终是否匹配到了与模式描述一致的字符串,或者只匹配到了一个字符串,都将以列表的形式返回。
使用示例:
>> import re
>> data = "There are some differences between python 2.7 and python 3.6."
>> re.findall('python\s\d\.\d', data)
['python 2.7', 'python 3.6']
>> re.findall('Python\s\d\.\d', data)
[]
>> re.findall('python\s3\.\d', data)
['python 3.6']
match
match
函数用以匹配字符串的开始部分,如果模式匹配成功,则返回一个 SRE_Match
类对象;如果匹配失败,则返回 None
,比如下面的例子:
>> re.match('python', 'python 3.6')
<_sre.SRE_Match object; span=(0, 6), match='python'>
>> assert re.match('3.6', 'python 3.6') is None
>>
通过上述的例子,我们发现 re.match
类似于字符串中的 startswith
函数,但 match
应用在正则表达式中更加强大,更富有表现力。比如下面的例子,我们判断一个字符串是否为数字开头,startswith
则无能为力;re 模块的 match
函数确可以轻松应对:
>> re.match('\d+', '123 我爱你')
<_sre.SRE_Match object; span=(0, 3), match='123'>
此外,通过观察 match
匹配成功时返回的 SRE_Match
对象,可知该对象包含了相关的模式和原始字符串,模式匹配成功的子串起止位置,也可以通过该对象获取匹配的字符串。
>> r = re.match('\d+', '123 我爱你')
>> r.re
re.compile(r'\d+', re.UNICODE)
>> r.string
'123 我爱你'
>> r.start()
0
>> r.end()
3
>> r.group()
'123'
search
re 模块的 search
函数在匹配字符串时,将在文本的任意位置开始进行匹配,并且在匹配成功时,立即返回。此外,re.search
函数在匹配成功时,也会返回一个 SRE_Match
对象。
search
函数与 match
函数用法几乎一样,区别在于前者在字符串的任意位置开始匹配,后者仅对字符串的开始部分进行匹配。他们的共同点是,如果匹配成功,返回 SRE_Match
对象;如果匹配失败,则返回一个 None
。
一个字符串包含多个模式的匹配时,search
只会返回第一个匹配的结果:
>> data = "There are some differences between python 2.7 and python 3.6."
>> r = re.search('\d.\d', data)
>> r
<_sre.SRE_Match object; span=(42, 45), match='2.7'>
>> r.group()
'2.7'
finditer
上文提到,re
仅仅查找第一次匹配。如果我们想要返回所有的结果,就需要用到前面提到的 findall
函数。除此之外,也可以使用 finditer
函数。
区别在于 finditer
返回一个迭代器,遍历迭代器可以得到一个 SRE_Match
对象,如下所示:
>> data = "There are some differences between python 2.7 and python 3.6."
>> r = re.finditer('\d.\d', data)
>> r
>> for it in r:
print(it.group())
2.7
3.6
二. 修改类函数
sub
re 模块的 sub
函数类似于字符串的 replace
函数,只是 sub
函数支持使用正则表达式,因此具有更广泛的使用场景,使用方式也更加灵活。
比如下面的例子,使用正则表达式的 sub
函数匹配并替换字符串中所有的 2.7
和 3.6
为空字符串:
>> data = "There are some differences between python 2.7 and python 3.6."
>> re.sub('\s*\d\.\d', '', data)
'There are some differences between python and python.'
此外,我们还可以使用 sub
函数和正则表达式实现更复杂的替换,比如将下面的日期进行格式化:
>> data = "today is 08/15/2021, python 2.7 is born at 07/03/2010 and python 3.6 is born at 12/23/2016."
>> re.subn(r'(\d+)/(\d+)/(\d+)', r'\3-\1-\2', data)
('today is 2021-08-15, python 2.7 is born at 2010-07-03 and python 3.6 is born at 2016-12-23.',
3)
split
re 模块的 split
函数与 Python 字符串的 split
函数功能一样,都是将一个字符串拆分成子串的列表。区别在于 re
模块的 split
函数能够使用正则表达式。
比如下面的例子,将包含各种符号分隔符的文本,拆分成单独的单词:
>> data = "There-are\n some\v differences,between:python 2.7\tand\r\npython 3.6."
>> re.split(r'[-\s,:]+', data)
['There',
'are',
'some',
'differences',
'between',
'python',
'2.7',
'and',
'python',
'3.6.']