python re.sub 正则表达式

目录

re.sub()前言

re.sub()函数原型

re.sub使用案例

re.sub替换单个数字或字母

re.sub替换多个数字或字母

re.sub 匹配固定形式

re.sub() 正则表达式提高部分

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替换单个数字或字母

(1)re.sub只替换单一数字

# 导入正则表达式需要的re模块
import re
s = "我的数字编号是123456,您能将我的编号数字变成星号吗?"
m_sub = re.sub(r'[0-9]', '*', s)
print(m_sub)
#结果为: 我的数字编号是******,您能将我的编号数字变成星号吗?

上面 re.sub(r'[0-9]', '*', s) 这句话则表示只匹配单一数字,并将每一个数字替换为一个星号 。

(2)re.sub只替换单一字母

# 导入正则表达式需要的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 替换多个数字或字母

注意:这里的所说的多个指的是大于等于一个。

(1)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) 这句话则表示匹配多个连续的数字,并将多个连续的数字替换为一个星号 。

(2)re.sub替换多个字母

# 导入正则表达式需要的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) 这句话则表示匹配多个连续的字母,并将多个连续的字母替换为一个星号 。

(3)re.sub替换多个数字和字母

# 导入正则表达式需要的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!

c. re.sub 去除以 ! 感叹号结尾的英文单词和数字

# 导入正则表达式需要的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 

d. re.sub 去除原始字符串中的URL

# 导入正则表达式需要的re模块
import re
s = "正则表达式的网站是http://www.xinbiancheng.cn/regular/ 您记住了吗?"
m_sub = re.sub(r'http[:.]+\S+', '', s)
print(m_sub)
#re.sub执行结果: 正则表达式的网站是 您记住了吗?

re.sub() 正则表达式提高部分

正则表达式-捕获组(capture group)

捕获组就是把正则表达式中子表达式匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用。当然,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部。

捕获组有两种形式,一种是普通捕获组,另一种是命名捕获组,通常所说的捕获组指的是普通捕获组。

语法如下:

普通捕获组:(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>