目录
一、简介
re 模块在python 中是一个内置模块 。让 Python 拥有了所有的正则表达式的功能
二、环境
本篇内容所使用的环境是: python 3.7 + re 模块
三、引用
import re
通过使用 re 模块来使用 python 中的 正则表达式
四、进入正文
1、为什么需要用 正则表达式 ?
a、问题------ 我们使用 python , 可能会遇到用户输入一个手机号码,然后需要对其输入的信息进行判断, 判断其是否满足电话号码 的要求。
如,用户输入一个 “12345678901” 。这明显不是一个手机号码该有的格式。那我们如何判断这个 字符串 是否是电话号码呢?
b、用 python 函数实现(自定义一个函数)
代码如下:
def checkPhone(phoneNum):
# pthoneNum 为用户传入的电话号码
# 1、首先电话号码是否都是数字
if phoneNum.isnumeric(): # 全是数字
# 判断该字符串是否是 11位
if len( phoneNum ) == 11: # 长度为 11 位
# 判断字符串第一位是否为 1 ,目前的手机号码首位都是 1
if phoneNum[0] == "1":
# 判断第二位数字是否为 3,4,5,7,8,9
if phoneNum[1] == "3" or phoneNum[1] == "5" or phoneNum[1] == "7" or phoneNum[1] == "8" or phoneNum[1] == "9":
# 如果第二位是 4 ,第三位必须是 7
return True
elif phoneNum[1] == "4" and phoneNum[2] == "7":
return True
else: # 第二位不是 3,4,5,7,8,9
print( "该电话号码 -- %s -- 第二位不是 3,4,5,7,8,9 " % (phoneNum) )
return False
else: # 第一位不为 1
print(" 该电话号码 -- %s -- 第一位不是 1 " % (phoneNum))
return False
else: # 长度不是 11 位
print(" 该电话号码 -- %s -- 长度不是 11 位 " %( phoneNum ) )
return False
else: # 不是全数字
print(" 该电话号码 -- %s -- 不是全数字 " %( phoneNum ) )
return False
# 用户的手机号码
str1 = "12345678901"
str2 = "13012312312"
str3 = "17620000000"
# 通过该函数判断是否是电话号码
res1 = checkPhone(str1)
res2 = checkPhone(str2)
res3 = checkPhone(str3)
print("当前号码 %s 是否是电话号码 %s " %(str1, res1) )
print("当前号码 %s 是否是电话号码 %s " %(str2, res2) )
print("当前号码 %s 是否是电话号码 %s " %(str3, res3) )
该方法可以简易判断一个字符串是否满足 “电话号码” 的要求。 但是该代码太冗余。各种判断语句,在刚开始写的时候很容易出错! 而且,如果运营商增加了一个 号码段 “12” 开头。 我们就需要 更改代码。 如果运营商说,手机号码增加至 12 位。 我们还需要改代码!
由此可知,代码的后期维护成本很高! 而且后期维护的话,需要另外一个人将该代码全部看一遍。比较浪费时间!
c、解决方法:( re 模块 )
使用 re 模块解决电话号码匹配问题,代码如下:
import re
def checkPhone(phoneNum):
# 正则表达式
pattern = r"^1([35789]\d|(47))\d{8}"
res = re.match( pattern , phoneNum )
return res
# 用户的手机号码
str1 = "12345678901"
str2 = "13012312312"
str3 = "14621499334"
# 通过该函数判断是否是电话号码
res1 = checkPhone(str1)
res2 = checkPhone(str2)
res3 = checkPhone(str3)
print("当前号码 %s 是否是电话号码 %s " %(str1, res1) )
print("当前号码 %s 是否是电话号码 %s " %(str2, res2) )
print("当前号码 %s 是否是电话号码 %s " %(str3, res3) )
将 两 段代码进行对比! 很清楚的发现, 代码量缩少了一半以上! 而且,如果后期运行商增加号段。我们只需要更改 pattern 所对应的 表达式即可!
所以为什么需要用 正则表达式,大家应该很清楚了吧!
正则表达式,其实就是某一类事务的一种规范! 如,电话号码, 它一定是 11 位数字, 以 1 开头等。 ipv4 地址 它点分十进制的话, 就是 每段 1-3 位数字。一共有四段! 且每段数字不能超过 255 。 我们就是 写好相应的规则(规范) ,然后以此规范去匹配相应的事物!
2、进入正文-------- 开始学习 “正则表达式”
2.1、re 模块 三大匹配函数 -------
a、re 模块简介( re.match() 函数 )
先看代码:
import re
print( re.match("w", "www.baidu.com") )
### 返回结果 ==> <re.Match object; span=(0, 1), match='w'>
print( re.match("ww", "www.baidu.com") )
### 返回结果 ==> <re.Match object; span=(0, 2), match='ww'>
print( re.match("a", "www.baidu.com") )
### 返回结果 ==> None
在此 代码中, 我们 用到了 re 模块中的一个方法 --------- re.match() 方法
*************** 开始学习 re.match() 方法 ******************
方法:
1、re.match()
原型:
re.match( pattern , string , flags = 0 )
参数说明:
pattern : 匹配的正则表达式 ---- (类似于某种规则,格式)
string : 要 匹配 的 字符串
flags: 标志位, 主要是用于 控制正则表达式的匹配方式, 值如下
默认值为 0. 就是不做任何设置。
值 | 说明 | 使用程度 |
re.I | 忽略大小写,大小写不敏感 | ❤❤❤❤ |
re.L | 做本地化识别 | |
re.M | 多行匹配, 影响 ^ 和 $ | ❤❤❤❤ |
re.S | 使 . 匹配包括换行符在内的所有字符(所有字符,如何不加该参数, . 无法匹配 换行符) | ❤❤ |
re.U | 根据 Unicode 字符集解析字符,影响 \w \W \b \B | ❤❤ |
re.X | 使我们以更灵活的格式理解 正则表达式 |
功能:
尝试从字符串的起始位置匹配一个模式( pattern ),如果不是起始位置,匹配成功的话,也会返回 None
分析:
re.match("w", "www.baidu.com")
因为 re.match() 函数 的 功能是 ----- 尝试从字符串的起始位置开始匹配一个模式。所以这个例子中, re.match() 方法 ,尝试从 “www.baidu.com” 的起始位置开始匹配一个模式(规则) "w", 刚好 字符串 “www.baidu.com” 的第一个字母就是 “w” . 所以。能正常匹配成功。 返回 匹配成功字符串的下标 <re.Match object; span=(0, 3), match='www'> 。 我们可以通过sapn() 方法获取匹配字符串的下标位置 。 re.match("www", "www.baidu.com").span()
#====> (0, 3)
b、re 模块简介( re.search() 函数 )
先看代码 -------
import re
print( re.search(r"good" , "python is a good language!" ) )
### ==> <re.Match object; span=(12, 16), match='good'>
print( re.search(r"god" , "python is a good language!" ) )
### ==> None
print( re.search(r"o" , "python is a good language!" ) )
### ==> <re.Match object; span=(4, 5), match='o'>
在此 代码中, 我们 用到了 re 模块中的一个方法 --------- re.search() 方法
*************** 开始学习 re.search() 方法 ******************
方法:
2、 re.search()
原型:
re.search( pattern , string , flags = 0 )
参数说明
pattern :匹配的正则表达式 ---- (类似于某种规则,格式)
string : 要 匹配 的 字符串
flags : 标志位, 值和 re.match 中的一样
功能:
扫描整个字符,并返回第一个成功的匹配
【注意】:该方法不需要从字符串的开头进行匹配
分析:
re.search( r"good" , "python is a good language!" )
因为,re.search() 方法的功能是,扫描整个字符,并返回第一个成的匹配。在该示例中, 我们要匹配的格式是: "good" , 而 匹配的 字符串 是 "python is a good language!" 。 该方法会从整个字符串中寻找与匹配模式一致的字符串。 所以找到了 “good”, 并返回其 所在位置的下标。 而 re.search(r"o" , "python is a good language!" ) 代码中 。 匹配模式 “ o” ,在 字符串中多次出现, 根据 re.search() 方法的功能所知, 它将返回找到第一个字符串的位置下标。 所以返回的是 “python” 中 的 “o” . 所属下标为:span = (4,5) !
c、re 模块简介( re.findall() 函数 )
先看代码 -------
import re
str = "python is a good language!C is a good language too! Java good too!"
print( re.findall("good",str ) )
### ==> ['good', 'good', 'good']
在此 代码中, 我们 用到了 re 模块中的一个方法 --------- re.findall() 方法
*************** 开始学习 re.findall() 方法 ******************
方法:
3、re.findall()
原型:
re.findall( pattern , string , flags = 0 )
参数说明:
pattern :匹配的正则表达式 ---- (类似于某种规则,格式)
string : 要 匹配 的 字符串
flags : 标志位, 值和 re.match 中的一样
功能:
扫描整个字符串,并返回结果列表! 返回的是一个 列表格式
【注意】:该方法,不需要从字符串的开始进行匹配!而是在整个字符串中查找
分析:
str = "python is a good language!C is a good language too! Java good too!"
re.findall("good",str )
因为,re.findall() 方法是在 整个字符串中进行查找匹配。 里面有几个匹配成功
的选项,他就会返回几个成功的匹配! 并以列表的形式的返回!
三个函数进行对比分析: re.match() 、 re.search() 、 re.findall()
序 | 函数 | 参数 | 说明 | 区别 |
1 | re.match() | pattern, string,flags | 从字符串的起始位置开始匹配,匹配成功返回结果,反之返回 None | 匹配位置 |
2 | re.search() | pattern, string,flags | 在整个字符串中进行匹配,返回第一个匹配的结果,反之返回 None | 返回结果为第一个匹配 |
3 | re.findall() | pattern, string,flags | 在整个字符串中进行匹配,返回所有的匹配结果,以列表的形式返回。无匹配返回 [ ] 空列表 | 返回所有匹配结果 |
2.2、正则表达式的元字符---- ( 单个字符匹配 )
概述: 我们首先看看,正则表达式中,如何匹配单个字符。难度还是用 26个英文字母代替? 难度匹配 "w" 就是用 “w” 的规则去匹配吗? 显然,不是! 要不然,工作量太大了!
首先我们来认识一下正则表达式中的 “ 元字符” -------- 匹配单个字符
序 | 元字符 | 说明 |
1 | . | 匹配除换行符以外的任意字符, (当 flags = re.S 时, "." 可以匹配任意字符) |
2 | [0123456789] | [] 是字符集合,表示匹配方括号中所包含的任意一个字符,这里相当于匹配任意一个数字 |
3 | [nice] | 匹配 “n” , "i" , "c" , "e" 中的任意一个字符 (可自行定义方阔号中的内容) |
4 | [a-z] | 匹配任意一个小写字母 |
5 | [A-Z] | 匹配任意一个大写字母 |
6 | [0-9] | 匹配任意一个数字,效果 同 ===》 [0123456789] |
7 | [a-zA-Z0-9] | 匹配任意一个小写字母、大写字母、数字 |
8 | [a-zA-Z0-9_] | 匹配任意一个小写字母、大写字母、数字以及下划线 |
9 | [^nice] | 匹配 除了 “n” , "i" , "c" , "e" 中的任意一个字符,^ 表示 非, 称为 脱字符 |
10 | [^0-9] | 匹配所有的 非数字 字符 |
11 | \d | 匹配所有的数字, 效果通 ===》 [0-9] , [01223456789] |
12 | \D | 匹配所有 非数字字符, 效果同 ===》 [^0-9] |
13 | \w | 匹配任意一个 数字、字母和下划线, 效果同 ===》 [0-9a-zA-Z] |
14 | \W | 匹配任意一个 非 数字、字母和下划线, 效果同 ===》 [^0-9a-zA-Z] |
15 | \s | 匹配任意的空白符(空格、换行、回车、换页、制表符等)效果同[ \f\n\r\t] |
16 | \S | 匹配 任意的 非空白符, 效果同 ===》 [^ \f\n\r\t] |
使用示例
1)、 .
import re
# .
print( re.search(r".", "www.baidu.com") )
###==> <re.Match object; span=(0, 1), match='w'>
"." 表示 匹配任意一个字符。 所以在此处就相当于匹配了 “w”
2)、[0123456789],[0-9]
import re
#[0123456789], [0-9]
print( re.search(r"[0123456789]", "www.baidu123.com") )
print( re.search(r"[0-9]", "www.baidu213.com") )
###==> <re.Match object; span=(9, 10), match='1'>
###==> <re.Match object; span=(9, 10), match='2'>
"[0123456789]" ,[0-9] 表示匹配 任意一个数字
3)、[a-zA-Z], [a-zA-Z0-9], [a-zA-Z0-9_]
import re
# [a-zA-Z], [a-zA-Z0-9], [a-zA-Z0-9_]
print( re.search( "[a-zA-Z]", "www.baidu.com") )
print( re.search( "[a-zA-Z]", "Www.baidu.com") )
print( re.search( "[a-zA-Z0-9]", "2ww.baidu.com") )
print( re.search( "[a-zA-Z0-9_]", "_ww.baidu.com") )
###==> <re.Match object; span=(0, 1), match='w'>
###==> <re.Match object; span=(0, 1), match='W'>
###==> <re.Match object; span=(0, 1), match='2'>
###==> <re.Match object; span=(0, 1), match='_'>
4)、[nice]
import re
print( re.search( "[nice]", "python is") )
###==> <re.Match object; span=(5, 6), match='n'>
5)、[^0-9]
import re
#[^0-9]
print( re.search( "[^0-9]", "www.baidu.com") )
print( re.search( "[^0-9]", "123Www.baidu.com") )
###==><re.Match object; span=(0, 1), match='w'>
###==><re.Match object; span=(3, 4), match='W'>
6)、 \d \D \w \W
import re
# \d \D \w \W \s \S
print( re.search(r"\d" , "www.baidu123.com") )
print( re.search(r"\D" , "www.baidu123.com") )
print( re.search(r"\w" , "www.baidu123.com") )
print( re.search(r"\W" , "123ww.baidu123.com") )
print( re.search(r"\s" , "123ww.baidu123.com\n") )
print( re.search(r"\S" , r"123ww.baidu123.com \n") )
###==> <re.Match object; span=(9, 10), match='1'>
###==> <re.Match object; span=(0, 1), match='w'>
###==> <re.Match object; span=(0, 1), match='w'>
###==> <re.Match object; span=(5, 6), match='.'>
###==> <re.Match object; span=(18, 19), match='\n'>
###==> <re.Match object; span=(0, 1), match='1'>
至此,我们知道如何用 正则表达式 去 匹配单个字符
2.3、正则表达式的锚字符 --- ( 边界字符 )
正则表达式中边界字符,有时可能会用上
序 | 锚字符 | 说明 |
1 | ^ | 行首匹配,和在[^]里面的 ^ 不是一个意思! 这里是表示以 xxx 字符开头 |
2 | $ | 行尾匹配,表示以 xxx 字符结尾 |
3 | \A | 匹配字符串的开始,它和 ^ 的区别是: " \A" 只匹配整个字符串的开头,即使在 re.M 模式下,也不会字符串第二行的行首 "^" 匹配字符串的行首 , 在 re.M 模式下可以匹配每一行的行首 |
4 | \Z | 匹配字符串的结束, 它和 $ 的区别是: "\Z" 只匹配整个字符串的结束。 re.M 模式下,也不会匹配某一行的行尾 "$" 匹配字符串的行尾, 但是在 re.M 模式下,可以匹配每一行的行尾 |
5 | \b | 匹配一个单词的边界,也就是指单词和空格间的位置 (遇到空格就是边界) |
6 | \B | 匹配非单词的边界 |
使用示例
1)、 ^
import re
# ^
print( re.search("^www" , "123www.baidu.com") )
print( re.search("^www" , "www.baidu.com") )
## ===> None
## ===> <re.Match object; span=(0, 3), match='www'>
在此处, ^ 现在表示以 xxx 字符开头。 代码中,就是匹配以 www 开头的字符串
2)、 $
import re
# $
print( re.search(r"com$" , "123www.baidu.com") )
print( re.search(r"com$" , "123www.baidu.com1") )
## ===> <re.Match object; span=(13, 16), match='com'>
## ===> None
在此处 , $ 表示以 xxx 字符结尾的字符串。 在代码中,表示以 "com" 结尾的字符串
3)、 \A
import re
# \A
print( re.findall( r"\Awww", "www.baidu.com") )
print( re.findall( r"^www", "www.baidu.com") )
print( re.findall( r"\Awww", "www.baidu.com\nwww.baidu.com") )
print( re.findall( r"^www", "www.baidu.com\nwww.baidu.com") )
print( re.findall( r"\Awww", "www.baidu.com\nwww.baidu.com", flags = re.M ) )
print( re.findall( r"^www", "www.baidu.com\nwww.baidu.com", flags = re.M ) )
## ===> ['www']
## ===> ['www']
## ===> ['www']
## ===> ['www']
## ===> ['www']
## ===> ['www', 'www']
\A 是以 xxx 开头匹配。 所以匹配到了 www 。 和 ^ 的功能类似。它们最大的区别在于,当flags = re.M 模式下, ^ 可以匹配多行 , 而 \A 只能匹配一行
【备注】: \n 表示换行符
4)、$
import re
print( re.findall( r"com\Z", "www.baidu.com") )
print( re.findall( r"com$", "www.baidu.com") )
print( re.findall( r"com\Z", "www.baidu.com\nwww.baidu.com") )
print( re.findall( r"com$", "www.baidu.com\nwww.baidu.com") )
print( re.findall( r"com\Z", "www.baidu.com\nwww.baidu.com", flags = re.M ) )
print( re.findall( r"com$", "www.baidu.com\nwww.baidu.com" , flags = re.M ) )
## ===> ['com']
## ===> ['com']
## ===> ['com']
## ===> ['com']
## ===> ['com']
## ===> ['com', 'com']
\Z 是以 xxx 字符结尾, 和 $ 功能类似, 最大的区别在于。 在 re.M 模式下, 可以匹配多行
5)、 \b \B
import re
# \b \B
print( re.findall(r"good\b" , "good language" ) )
print( re.findall(r"good\B" , "good language" ) )
print( re.findall(r"good\b" , "goodlanguage" ) )
print( re.findall(r"good\B" , "goodlanguage" ) )
## ===> ['good']
## ===> []
## ===> []
## ===> ['good']
\b 和 \B 是匹配单词与非单词的边界!
第一行代码中, good 是一个单词, 因为good 后面有一个空格,所以能 匹配成功。
第二行代码中, \B 是匹配非单词边界,而good 是一个单词,所以匹配失败。
第三行代码中, \b 匹配单词边界, 而 goodlanguage 是一个单词,所以匹配失败
第四行代码中, \B 是匹配非单词边界, 而 goodlanguage 是一个单词,而good 是非单词,所以能匹配成功
2.4、正则表达式的多字符匹配
利用正则表达式,匹配一个或多个字符。 这个是经常需要用到的
说明:下方的 x,y,z 都是普通字符, m,n 为 非负整数 。 不是正则表达式的元字符
序 | 多字符匹配 | 说明 |
1 | (xyz) | 匹配小括号内的 xyz , () 内的作为一个整体去匹配 |
2 | x? | 匹配 0 个或者 1个 x |
3 | x* | 匹配 0 个 或者 任意多个 x (.*) ==> 表示匹配 0个 或任意多个字符 换行符除外 |
4 | x+ | 匹配至少一个 x |
5 | x{n} | 匹配确定个数的 n 个 x |
6 | x{n , } | 匹配 至少 n 个 x |
7 | x{ n , m } | 匹配至少 n 个 x, 最多 m 个 x 。 注意 n <= m |
8 | x|y | | 表示 或, 匹配的是 x 或者 y |
示例示例
1)、 (xyz)
import re
# (xyz)
print( re.findall( r"(good)", "python is a good language") )
print( re.findall( r"(god)", "python is a good language") )
print( re.findall( r"(ang)", "python is a good language") )
## ===> ['good']
## ===> []
## ===> ['ang']
在此处, 我们将 "good" 作为一个整体去匹配。 所有能匹配到 good 。 我们将 "god" 作为整体的时候, 字符串中不存在这样的一个整体, 所以匹配结果为空。
当我们把 “ang” 作为一个整体匹配时, 在 “language” 中存在这样的 一个整体, 所以我们能匹配成功
2)、 x?
import re
# x?
print( re.findall( r"a?", "language" ) )
print( re.findall( r"x?", "language" ) )
## ===> ['', 'a', '', '', '', 'a', '', '', '']
## ===> ['', '', '', '', '', '', '', '', '']
x? 表示 匹配 0 个 或 1 个 x . 在代码中。
第一行,我们 匹配 a? 。 表示我们匹配 0 个 或者 1 个 a . 而 "language" 中, 第一个字母是“l” , 所以 匹配到 0 个 a, 因此返回 “”, 而第二个字母是 a , 匹配 0 个 或 1 个 a, 所以匹配到 一个 “a” . 因此 返回 “a” , 以此类推……
3)、 x*
import re
## x*
print( re.findall( r"a*", "laanguage" ) )
print( re.findall( r"x*", "laanguage" ) )
## ===> ['', 'aa', '', '', '', 'a', '', '', '']
## ===> ['', '', '', '', '', '', '', '', '']
x* 表示匹配 0 个 或任意多个 x, 所以 a* 表示 匹配 0 个 a , 或者任意多个 a
4)、 x+
import re
# x+
print( re.findall(r"a+", "laanguage" ) )
print( re.findall(r"x+", "laanguage" ) )
## ===> ['aa', 'a']
## ===> []
x+ 表示 匹配 至少一个x . 所以在代码中, “a+” 表示 匹配至少一个 a .
5)、x{n} , x{ n, }, x{n,m}
import re
# x{n} , x{n,} , x{n,m}
print( re.findall( r"a{3}", "aaabaacaaaaa") )
print( re.findall( r"a{2,}", "aaabaacaaaaa") )
print( re.findall( r"a{2,4}", "aaabaacaaaaa") )
## ===> ['aaa', 'aaa']
## ===> ['aaa', 'aa', 'aaaaa']
## ===> ['aaa', 'aa', 'aaaa']
x{n} 表示 匹配 具体数目的 x . 如本代码中 3个 a . 【注意】 必须是在一起的 a, 不能分开
x{n,} 表示 匹配 至少 n 个 x
x{n,m} 表示 匹配 n 到 m 个 x. 在这个区间范围都可以
6)、 x|y
import re
# x|y
print( re.findall( r"a|g" , "laanguage") )
## ===> ['a', 'a', 'g', 'a', 'g']
x|y 表示 匹配 x 或者 y
【注意】: x , y 是一个整体进行匹配
【注意】
1、*? +? x? 最小匹配
2、通常都是尽可能多的匹配, 可以使用这种带 ? 的方式解决 贪婪匹配问题
3、 (?:x) 类似于 (xyz) , 但是不表示一个组
问题:
匹配 C 语言中 的注释
如: /* part1 */ /* part2 */ /* part3 */
希望返回的结果是 [ /* part1 */, /* part2 */, /* part2 */ ]
解决代码:
import re
str1 = r" /* part1 */ /* part2 */ /* part3 */"
print( re.findall( r"//*.*?/*/", str1 ) )
## ===> ['/* part1 */', '/* part2 */', '/* part3 */']
上面的代码可以领悟一下!
【提示】
* 是 正则表达式中的元字符, 所以有时候需要进行转义。 不转义可能会出错
2.5、re 模块 深入------- 高级用法
a、字符串切割 ------ split() 函数
re.split() 函数 可以对字符串进行切割
import re
# 原始方式
str1 = "python is a good language"
print( str1.split(" ") )
# re 模块进行切割
print( re.split(r" +", str1 ) )
好处是, 我们不用在意字符串中,有多少个“空格”, 我们通过 pattern 对 切割的字符串
进行规范!从而得到我们想要的字符串
用法: re.split( pattern , string )
pattern : 正则表达式
string: 需要切割的字符串
b、re.finditer() 函数
原型: finditer(pattern, string, flags=0)
参数: 与 re.match() 、 re.serach() 、 re.findall() 参数一致
功能: 与 findall 功能类似, 扫描整个字符串, 返回的是一个 迭代器
findall() 函数返回的是一个列表的形式。 如果数据量比较大, 可能会造成内
存溢出现象
import re
str2 = "python is a good language, C is a nice language , JAVA is a handsome language"
d = re.finditer(r"(language)", str2 ) # 预防内存溢出
while True:
try:
l = next( d )
print( l )
except StopIteration as e:
break
re.finditer() 返回的是一个迭代器。 所以我们可以用 next() 方法, 每次从其中取一条数
据, 但是因为取到最后一条是,迭代器会报错。 所以,需要用 try 去捕获异常 。
c、字符串的替换和修改
re.sub() 函数
re.subn() 函数
原型:
re.sub(pattern, repl, string, count=0, flags=0)
re.subn(pattern, repl, string, count=0, flags=0)
参数:
pattern: 正则表达式
repl: 指定的用来替换的字符串
string: 目标字符串
count: 最多的替换次数 , 默认为 0, 表示 ,全部替换
flags: 与其他方法中 flags 参数, 用法全部一样
功能:
在模板字符串中, 以正则表达式的规则匹配字符串。 再把他们替换成指定的
字符串。 可以指定替换的次数,如果不指定,默认替换所有匹配的字符串
sub 和 subn 的区别:
前者返回一个被替换的字符串。 后者返回一个元组,第一个元素时被替换的
字符串,第二个元素时替换的次数
import re
str = "Python a good language, C a nice language, Java a lihai language"
print( " sub = ", re.sub(r"(language)", "yuyan" , str ) )
print( type( re.sub( r"(language)", "yuyan" , str ) ) )
print( " subn = ", re.sub(r"(language)", "yuyan" , str ) )
print( type( re.subn( r"(language)", "yuyan" , str ) ) )
2.6、re 模块高级用法 ------ 分组
概念:
除了简单的判断是否匹配之外, 正则表达式还有提取子串的功能。
用 () 表示 分组。 () 是我们提取出来的分组
查看代码:
import re
str1 = "010-12345678"
m = re.match( r"(\d{3})-(\d{8})", str1 )
print( m )
print( m.group() )
print( m.groups() )
print( m.group(0) )
print( m.group(1) )
print( m.group(2) )
### === > <re.Match object; span=(0, 12), match='010-12345678'>
### === > 010-12345678
### === > ('010', '12345678')
### === > 010-12345678
### === > 010
### === > 12345678
我们可以使用小括号, 将我们需要的数据括起来。
使用序号,获取对应组的信息
groups() 表示 匹配的各组的情况
group(0) 表示原始字符串
group(1) 表示一个小括号
group(2) 表示第二个小括号 ------ 有几个小括号,数字就有几个
给 各组添加名字 ------ 在 分组的 () 内 添加 ?P<组名称> ------ 访问方式 group(“组名”)
import re
str1 = "010-12345678"
m = re.match( r"(?P<first>\d{3})-(\d{8})", str1 )
print( m.group("first"))
### === > 010
2.7、re 模块高级用法 ------ 编译
概述:
当我们使用正则表达式时, re 模块会干两件事
1、编译正则表达式,如果正则表达式本身不合法,会报错(抛出异常)
2、用编译后的正则表达式去匹配对象
re.compile() 方法
参数:
pattern: 要编译的表达式
flags: 与以前一致
import re
strNum = "13000000000"
pat = r"^1(([3578]\d)|(47))\d{8}$"
### 将正则表达式进行编译 , 后续只需要用该参数进行调用即可
re_telephon = re.compile( pat )
### 用对象调用
print( re_telephon.match( strNum ) )
### ====> <re.Match object; span=(0, 11), match='13000000000'>
将正则表达式编译后, 我们可以直接用编译后的对象调用相关的函数。 可以不用每次
都重复写正则表达式! 如果涉及到更改正则表达式, 只需要更改编译的正则表达式。后面调
用的方法无需修改
五、结束
希望本篇 关于 正则表达式的文章能帮到各位!
文中如有错误或不当之处,还请大佬指出纠正! 鄙人菜鸟一枚~~~~~ 不胜感激涕零