Python内置库之正则表达式re
导入正则表达式re库
import re
原始字符串
在Python中,使用 r 或者 R 作为前缀的字符串称为原始字符串,原始字符串将字符串中的所有内容视为普通字符串,不会进行转义
print('D:\note')
# 输出结果会将 \n 作为换行符
"""
D:
ote
"""
print(r'D:\note')
# 输出结果
"""
D:\note
"""
正则表达式对象替换
compile()
函数将字符串转换为正则表达式对象
- 返回值为正则对象
- 转换后可直接使用此正则表达式对象调用匹配、替换、分割的方法,不需要再传入正则表达式参数
- 此方法可用于 需要多次使用此正则表达式的场景
pattern = 'hogwarts'
prog = re.compile(pattern)
s = 'hogwarts class'
print(prog.match(s))
print(prog.search(s))
匹配字符串
match()
从字符串开头进行匹配,若开头无法匹配则匹配失败,函数返回None
语法:re.match(pattern, string, [flags])
- pattern:正则表达式
- string:要进行匹配的字符串
- flags:可选,控制匹配方式,使用方式:
re.A
- A:只进行ascii匹配
- I:不区分大小写
- M:将^和$用于包括整个字符串开始和结尾的每一行
- X:忽略模式字符串中未转义的空格和注释
返回值:匹配成功则返回一个匹配对象,失败则返回None
pattern = r'hogwarts'
s = 'Hogwarts class'
s1 = 'today we learning hogwarts class in hogwarts'
match1 = re.match(pattern, s, re.I)
print(match1)
print(f'匹配值的起始位置:{match1.start()}')
print(f'匹配值的结束位置:{match1.end()}')
print(f'匹配值开始与结束位置的元组:{match1.span()}')
print(f'需要进行匹配的字符串:{match1.string}')
print(f'匹配出的数据:{match1.group()}')
# 因为match是从字符串开始位置进行匹配,因此s1匹配不到,返回None
match2 = re.match(pattern, s1, re.I)
print(match2)
"""
<re.Match object; span=(0, 8), match='Hogwarts'>
匹配值的起始位置:0
匹配值的结束位置:8
匹配值开始与结束位置的元组:(0, 8)
需要进行匹配的字符串:Hogwarts class
匹配出的数据:Hogwarts
None
"""
search()
扫描整个字符串并返回第一个成功的匹配
语法:re.search(pattern, string, [flags])
返回值:匹配成功则返回一个匹配对象,失败则返回None
用法同上
pattern = r'hogwarts'
s = 'Hogwarts class'
s1 = 'today we learning hogwarts class in hogwarts'
match1 = re.search(pattern, s, re.I)
print(match1)
# search是在整个字符串中进行匹配,因此s1匹配成功,但是只匹配一次
match2 = re.search(pattern, s1, re.I)
print(match2)
print(f'匹配值的起始位置:{match2.start()}')
print(f'匹配值的结束位置:{match2.end()}')
print(f'匹配值开始与结束位置的元组:{match2.span()}')
print(f'需要进行匹配的字符串:{match2.string}')
print(f'匹配出的数据:{match2.group()}')
"""
<re.Match object; span=(0, 8), match='Hogwarts'>
<re.Match object; span=(18, 26), match='hogwarts'>
匹配值的起始位置:18
匹配值的结束位置:26
匹配值开始与结束位置的元组:(18, 26)
需要进行匹配的字符串:today we learning hogwarts class in hogwarts
匹配出的数据:hogwarts
"""
findall()
在整个字符串中搜索所有符合正则表达式的字符串,返回列表
语法:re.findall(pattern, string, [flags])
match3 = re.findall(pattern, s1)
print(match3)
# 可以看见,search方法只匹配一次,所以当需要进行多次匹配时,可以使用findall()方法
"""
['hogwarts', 'hogwarts']
"""
pattern1 = r'[0-9]+[a-z]*\?'
s2 = '12test?57cases32simples?hello'
match4 = re.findall(pattern1, s2)
print(match4)
"""
['12test?', '32simples?']
"""
替换字符串
sub()
进行字符串替换
语法:re.sub(pattern, repl, string, [count], [flags])
- pattern:正则表达式
- repl:要替换成的字符串
- string:要被查找替换的原始字符串
- count:可选,表示替换的最大次数,默认为0,表示替换所有匹配
- flags:可选,控制匹配方式
返回值:替换后的字符串
# 我们需要将符合正则的电话号码进行加密替换
pattern2 = r'1[3-9]\d{9}'
s3 = 'tel:13712341234,tel1:15700010001,客服热线:1001001'
res = re.sub(pattern2, '1**********', s3)
print(res)
"""
tel:1**********,tel1:1**********,客服热线:1001001
"""
当需要对匹配的字符串做复杂处理时,repl可以为一个函数,对匹配结果进行处理后返回要替换成的字符串即可。
matched对象和分组
当我们需要得到匹配出的数据中的某些部分内容时,可以对正则表达式使用()
来进行分组,待匹配成功得到匹配对象后,通过匹配对象的方法:方法groups()
和group(num=0)
,可以获得分组信息(这两个方法是匹配对象所有的,findall和split这样返回列表的就没有)
# 简单示例,通过()进行分组
pattern = r'(hog)w(arts)'
s = 'Hogwarts class'
s1 = 'today we learning hogwarts class in hogwarts'
# match1为返回的匹配对象
match1 = re.search(pattern, s, re.I)
print(f'match1:{match1}')
# groups()返回一个元组,元组元素为所有匹配到的小组
print(f'match1匹配出的所有小组:{match1.groups()}')
# group(num=0)没有参数时,num默认为0,意为匹配到的整个完整字符
print(f'匹配到的完整字符:{match1.group()}')
# group(1)指定num=1,意为匹配到的完整字符中的第一个小组,这里是Hog
print(f'匹配到的第一个组:{match1.group(1)}')
# 可以在group中一次输入多个组号,会返回一个包含这些组对应内容的元组
print(f'匹配到的第一、第二个组:{match1.group(1, 2)}')
"""
match1:<re.Match object; span=(0, 8), match='Hogwarts'>
match1匹配出的所有小组:('Hog', 'arts')
匹配到的完整字符:Hogwarts
匹配到的第一个组:Hog
匹配到的第一、第二个组:('Hog', 'arts')
"""
# search()方法返回的匹配对象也拥有相同的方法
那么当我们需要对匹配到的完整内容的部分数据做处理时,分组就派上用场了,我们可以根据需要通过()
对正则表达式进行分组,再对分组后的内容做处理,然后完成匹配数据的部分内容替换
# 将电话号码的中间四位做加密处理
# 我们将中间四位的前后内容进行分组
pattern2 = r'(1[3-9]\d)\d{4}(\d{4})'
s3 = 'tel:13712341234,tel1:15700010001,客服热线:1001001'
# 获得中间四位的前后内容,再和加密内容进行拼接
def _rep(matched):
first, thr = matched.group(1, 2)
result = first + '****' + thr
return result
# 每次匹配到的内容,会通过第二个参数的内容进行替换
# 这里会将匹配对象matched传递给_rep函数,然后使用返回值替换正则表达式匹配到的整个字符串
res = re.sub(pattern2, _rep, s3)
print(res)
"""
tel:137****1234,tel1:157****0001,客服热线:1001001
"""
分割字符串
split()
根据正则表达式分割字符串,返回列表
语法:re.split(pattern, string, [maxsplit], [flags])
- pattern:正则表达式
- string:要匹配进行分割的字符串
- maxsplit:可选,最大分割次数
- flags:可选,控制匹配方式
返回值:分割后的列表
pattern2 = r'1[3-9]\d{9}'
s3 = 'tel:13712341234,tel1:15700010001,客服热线:1001001'
res1 = re.split(pattern2, s3)
print(res1)
"""
['tel:', ',tel1:', ',客服热线:1001001']
"""