python re.sub 正则表达式
目录
re.sub() 前言
在字符串数据处理的过程中,正则表达式是我们经常使用到的,python中使用的则是re模块。
下面会通过实际案例介绍 re.sub() 的详细用法,re.sub()函数主要用于替换字符串中的匹配项。
re.sub() 函数原型
首先从python源代码来看一下该函数原型,包括各个参数及其意义:
def sub(pattern, repl, string, count=0, flags=0):
"""Return the string obtained by replacing the leftmost
non-overlapping occurrences of the pattern in string by the
replacement repl. repl can be either a string or a callable;
if a string, backslash escapes in it are processed. If it is
a callable, it's passed the Match object and must return
a replacement string to be used."""
return _compile(pattern, flags).sub(repl, string, count)
从上面的代码中可以看到re.sub()方法中含有5个参数:
-
(1)pattern:该参数表示正则表达式中的模式字符串;
-
(2)repl:该参数表示要替换的字符串(即匹配到pattern后替换为repl),也可以是个函数;
-
(3)string:该参数表示要被处理(查找替换)的原始字符串;
-
(4)count:可选参数,表示是要替换的最大次数,而且必须是非负整数,该参数默认为0,即所有的匹配都会被替换;
-
(5)flags:可选参数,表示编译时用的匹配模式(如忽略大小写、多行模式等),数字形式,默认为0。
其中re.sub函数的前3个参数是必填项,后面两个参数是可选参数。
re.sub使用案例
使用re.sub正则表达式替换所有小写字母a,变成大写字母A
# 导入正则表达式需要的re模块
import re
# sub 第一个参数是正则表达式 ,第二个参数表示要替换的字符串,第三个参数是源字符串
m_sub = re.sub(r'a', "A", 'I am a lowercase letter a, I am a lowercase letter b')
print(m_sub)
#结果为: I Am A lowercAse letter A, I Am A lowercAse letter b
re.sub替换单个数字或字母
# 导入正则表达式需要的re模块
import re
s = "我的数字编号是123456,您能将我的编号数字变成星号吗?"
m_sub = re.sub(r'[0-9]', '*', s)
print(m_sub)
#结果为: 我的数字编号是******,您能将我的编号数字变成星号吗?
上面 re.sub(r'[0-9]', '*', s) 这句话则表示只匹配单一数字,并将每一个数字替换为一个星号 。
# 导入正则表达式需要的re模块
import re
s = "My number is 123456, can you turn my number into an asterisk?"
m_sub = re.sub(r'[a-z]', '*', s)
print(m_sub)
#结果为: M* ****** ** 123456, *** *** **** ** ****** **** ** ********?
m_sub = re.sub(r'[A-Z]', '*', s)
print(m_sub)
#结果为: *y number is 123456, can you turn my number into an asterisk?
m_sub = re.sub(r'[A-Za-z]', '*', s)
print(m_sub)
#结果为: ** ****** ** 123456, *** *** **** ** ****** **** ** ********?
上面 re.sub(r'[a-z]', '*', s) 这句话则表示只匹配单一小写字母,并将每一个小写字母替换为一个星号 。
上面 re.sub(r'[A-Z]', '*', s) 这句话则表示只匹配单一大写字母,并将每一个大写字母替换为一个星号 。
上面 re.sub(r'[A-Za-z]', '*', s) 这句话则表示只匹配单一字母,并将每一个字母替换为一个星号 。
re.sub 替换多个数字或字母
注意:这里的所说的多个指的是大于等于一个。
# 导入正则表达式需要的re模块
import re
s = "My number is 123456, can you turn my number into an asterisk?"
m_sub = re.sub(r'[0-9]+', '*', s)
print(m_sub)
# My number is *, can you turn my number into an asterisk?
上面 re.sub(r'[0-9]+', '*', s) 这句话则表示匹配多个连续的数字,并将多个连续的数字替换为一个星号 。
# 导入正则表达式需要的re模块
import re
s = "My number is 123456, can you turn my number into an asterisk?"
m_sub = re.sub(r'[a-z]+', '*', s)
print(m_sub)
# M* * * 123456, * * * * * * * *?
m_sub = re.sub(r'[A-Z]+', '*', s)
print(m_sub)
# *y number is 123456, can you turn my number into an asterisk?
m_sub = re.sub(r'[a-zA-Z]+', '*', s)
print(m_sub)
# * * * 123456, * * * * * * * *?
上面 re.sub(r'[a-z]+', '*', s) 这句话则表示匹配多个连续的小写字母,并将多个连续的小写字母替换为一个星号 。
上面 re.sub(r'[A-Z]+', '*', s) 这句话则表示匹配多个连续的大写字母,并将多个连续的大写字母替换为一个星号 。
上面 re.sub(r'[A-Za-z]+', '*', s) 这句话则表示匹配多个连续的字母,并将多个连续的字母替换为一个星号 。
# 导入正则表达式需要的re模块
import re
s = "My number is 123456, can you turn my number into an asterisk?"
m_sub = re.sub(r'[0-9a-zA-Z]+', '*', s)
print(m_sub)
# 结果为: * * * *, * * * * * * * *?
上面 re.sub(r'[0-9A-Za-z]+', '*', s) 这句话则表示匹配多个连续的数字和字母,并将多个连续的数字、连续的字母、连续的数字和字母替换为一个星号 。
re.sub 匹配固定形式
a. re.sub 只保留字母和空格,将 repl 设置为空字符即可。
# 导入正则表达式需要的re模块
import re
s = "My number is 123456, can you turn my number into an asterisk?"
m_sub = re.sub(r'[^a-z ]', '', s)
print(m_sub)
# re.sub执行结果为: y number is can you turn my number into an asterisk
m_sub = re.sub(r'[^a-z ]+', '', s)
print(m_sub)
# re.sub执行结果为: y number is can you turn my number into an asterisk
m_sub = re.sub(r'[^A-Za-z ]', '', s)
print(m_sub)
# re.sub执行结果为: My number is can you turn my number into an asterisk
m_sub = re.sub(r'[^A-Za-z ]+', '', s)
print(m_sub)
# re.sub执行结果为: My number is can you turn my number into an asterisk
如果要使句子语义和结构更完整,则要先将其余字符替换为空格(即repl设置为空格),然后去除多余的空格,如下:
# 导入正则表达式需要的re模块
import re
s = "My number is 123456, can you turn my number into an asterisk?"
m_sub = re.sub(r'[^A-Za-z ]+', ' ', s)
print(m_sub)
# My number is can you turn my number into an asterisk
m_sub1 = re.sub(r'[ ]+', ' ', m_sub)
# 正则表达式 r'[ ]+' 可以去掉多个重复的连续空格为一个空格
print(m_sub1)
# My number is can you turn my number into an asterisk
b. re.sub 去除以 @ 开头的英文单词
# 导入正则表达式需要的re模块
import re
s = "zhangsan @song welcome to xinbiancheng.cn!"
m_sub = re.sub(r'@[A-Za-z]+', '', s)
print(m_sub)
# zhangsan welcome to xinbiancheng.cn!
# 导入正则表达式需要的re模块
import re
s = "zhangsan @song welcome to baidu!"
m_sub = re.sub(r'[0-9A-Za-z]+!', '', s)
print(m_sub)
# zhangsan @song welcome to
# 导入正则表达式需要的re模块
import re
s = "正则表达式的网站是http://www.xinbiancheng.cn/regular/ 您记住了吗?"
m_sub = re.sub(r'http[:.]+\S+', '', s)
print(m_sub)
#re.sub执行结果: 正则表达式的网站是 您记住了吗?
re.sub() 正则表达式提高部分
捕获组就是把正则表达式中子表达式匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用。当然,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部。
捕获组有两种形式,一种是普通捕获组,另一种是命名捕获组,通常所说的捕获组指的是普通捕获组。
语法如下:
普通捕获组:(Expression)
命名捕获组:(?<name>Expression)
您能提炼出 "xinbiancheng" 并在它的后面加上 ".cn" 吗?
# 导入正则表达式需要的re模块
import re
inputStr = "hello xinbiancheng, nihao xinbiancheng";
replacedStr = re.sub(r"hello (\w+), nihao \1", r"\1.cn", inputStr);
print(replacedStr)
# re.sub正则表达式执行结果 xinbiancheng.cn
inputStr = "hello xinbiancheng, nihao xinbiancheng";
replacedStr = re.sub(r"hello (?P<name>\w+), nihao (?P=name)", "\g<name>.cn", inputStr);
print(replacedStr)
# re.sub正则表达式执行结果 xinbiancheng.cn
re.sub 如何提炼日期,并且替换日期格式
# 导入正则表达式需要的re模块
import re
a = re.sub('(\d{4})-(\d{2})-(\d{2})', r'\2-\3-\1', '2021-06-08')
# re.sub 正则表达式 普通捕获组
print(a)
#06-08-2021
a = re.sub('(\d{4})-(\d{2})-(\d{2})', r'\g<2>-\g<3>-\g<1>', '2021-06-08')
# re.sub 正则表达式 普通捕获组
print(a)
#06-08-2021
a = re.sub('(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})', r'\g<m>-\g<d>-\g<y>', '2021-06-08')
# re.sub 正则表达式 命名捕获组
print(a)
#06-08-2021
re.sub() 第二个参数是函数的用法
# 导入正则表达式需要的re模块
import re
def replace_num(str):
numDict = {'0':'〇','1':'一','2':'二','3':'三','4':'四','5':'五','6':'六','7':'七','8':'八','9':'九'}
return numDict[str.group()]
my_str = '2021年6月8号'
a = re.sub(r'(\d)', replace_num, my_str)
print(a) # 每次匹配一个数字,执行函数,获取替换后的值
# re.sub正则表达式运行结果: 二〇二一年六月八号
re.sub 实战演练
使用正则表达式的 re.sub 去掉 html 中的a标签
# 导入正则表达式需要的re模块
import re
html = '''<div id="songs-list">
<h2 class="title">经典老歌</h2>
<p class="introduction">
经典老歌列表
</p>
<ul id="list" class="list-group">
<li data-view="2">一路上有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一声笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦">往事随风</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
<li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
<li data-view="5">
<a href="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''
html = re.sub('<a.*?>|</a>', '', html)
print(html)
re.sub 运行结果为:
<div id="songs-list">
<h2 class="title">经典老歌</h2>
<p class="introduction">
经典老歌列表
</p>
<ul id="list" class="list-group">
<li data-view="2">一路上有你</li>
<li data-view="7">
沧海一声笑
</li>
<li data-view="4" class="active">
往事随风
</li>
<li data-view="6">光辉岁月</li>
<li data-view="5">记事本</li>
<li data-view="5">
但愿人长久
</li>
</ul>
</div>