正则表达式
Python中有关正则表达式的内容在re模块中,要想使用正则表达式必须先包含re模块
import re
注意:在一个正则表达式前面,最好加上原生字符‘r’,因为正则表达式有一些元字符以‘\’开头,比如‘\b’表示数字,那么因为字符串中‘\’需要用‘\\’来表示,所以就需要写成‘\\b’,但若加上了‘r’,就只需要写上‘\b’,省去了一些麻烦
一些常用的元字符
元字符在正则表达式中的写法 | 意义 |
---|---|
\\ | 字符\ |
. | 任意一个字符,flags = re.DOTALL时,包括换行符 |
\. | 字符. |
\d | 0~9之间的任意一个数字 |
\D | 不是0~9之间的数字的任意一个字符 |
\s | 一个空格类字符:’\t’、‘\n’、’\x0B’、’\f’、’\r’ |
\S | 一个非空格类字符 |
\w | 可用于标识符的字符 |
\W | 不可用于标识符的字符 |
\p{Punct} | 标点符号:!"#$%^&*()_+=等等 |
\A | 匹配字符串的开始位置 |
\Z | 匹配字符串的结束位置 |
^ | 匹配字符串的开始位置,flags = re.M时,也匹配换行符之后的位置 |
$ | 匹配字符串的结束位置,flags = re.M时,也匹配换行符之前的位置 |
\数字 | 表示引用对应分组的内容 |
常用限定修饰符
限定修饰符的用法(X表示正则表达式) | 意义 |
---|---|
X? | X出现0次或者1次 |
X* | X出现0次、1次或者多次(闭包) |
X+ | X出现0次或者1次(正闭包) |
X{n} | X恰好出现n次 |
X{n,} | X至少出现n次 |
X{n,m} | X出现n或者m次 |
分组
Python中允许将正则表达式分组
将正则表达式用一对小括号括起来成为一个组(组也是一个正则表达式),这些组是有编号的,从1开始,从左到右依次递增(以左括号为基准),上限是99。每一个分组都是单独的分匹配,其匹配情况也会单独保存。
若不想使用分组模式,也就是不需要对与组匹配的内容进行提取或处理,可以使用**(?:…)**,也就是在分组最前面加上"?:",这样就不会保存其匹配情况。
匹配对象
由于下面的方法有一些会返回匹配对象,所以我先说一下匹配对象的方法
group()
Match.group([group1, ...])
- 当没有参数时:返回整个匹配的字符串
- 当参数为一个时:
- 当参数为0时,其等价于没有参数
- 当参数对应的组号存在时,返回该组的匹配的字符串
- 当参数为不存在的组号时,抛出IndexError异常
- 当参数为多个时,将参数对应的组所匹配的字符串打包成一个元组返回
另外,Python还提供了更加简便的访问方法,可以直接使用中括号来访问
Match.__getitem__(g)
m[g] 等价于m.group(g)
groups()
Match.groups(default=None)
返回由所有组匹配的字符串组成的元组,没有匹配的组用default填充
start()
Match.start([group])
- 当没有参数时,返回整个匹配的字符串开始的位置
- 当有参数时:
- 当参数为0时:其等价于没有参数
- 当参数对应的组号存在时:返回该组的匹配的字符串的位置
- 当参数为不存在的组号时:抛出IndexError异常
end()
Match.end([group])
作用同上,只是变为了结束位置(其是匹配字符串最后一个字符的位置+1)
span()
Match.span([group])
返回一个元组(m.start(group), m.end(group))
有关匹配对象的例子与正则表达式常用方法一块举例
常用方法
re模块常用的方法
match()
re.match(pattern, string, flags=0)
-
pattem:正则表达式
-
string:被查找的字符串
-
flags:标志位,用于控制正则表达式的匹配模式,大致的说明如下图,标志前要加上re.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w9RtaHND-1622449238286)(E:/笔记/Python学习/08.字符串的使用技巧/assets/1581923114506.png)]
判断string是否与patterm完全匹配,若匹配,返回一个匹配对象,否则返回None,例如
import re
print(re.match(r"(a(b))c", "abc").group())# abc
print(re.match(r"(a(b))c", "abc").group(1))# ab
print(re.match(r"(a(b))c", "abc")[2])# b
print(re.match(r"(a(b))c", "abc").groups())# ('ab', 'b')
print(re.match(r"(a(b))c", "abc").start())# 0
print(re.match(r"(a(b))c", "abc").start(1))# 0
print(re.match(r"(a(b))c", "abc").start(2))# 1
print(re.match(r"(a(b))c", "abc").end())# 3
print(re.match(r"(a(b))c", "abc").end(1))# 2
print(re.match(r"(a(b))c", "abc").end(2))# 2
print(re.match(r"(a(b))c", "abc").span())# (0, 3)
print(re.match(r"(a(b))c", "abc").span(1))# (0, 2)
print(re.match(r"(a(b))c", "abc").span(2))# (1, 2)
search()
re.search(pattern, string, flags=0)
参数同上
判断string是否存在子串与pattern匹配,若存在,返回一个匹配对象
import re
print(re.search(r"(a(b))c", "deabcf").group())# abc
findall()
re.findall(pattern, string, flags=0)
参数同上
若pattern中没有分组,则寻找string中所有与pattern匹配的字符串,全部打包成一个列表后返回,例如
import re
print(re.findall(r"\d+\w", "123abc456d"))# ['123a', '456d']
若只有一个分组,则寻找string中所有与pattern中的组匹配的字符串,组成列表后返回,例如
import re
print(re.findall(r"(\d+)\w", "123abc456d"))# ['123', '456']
否则,就string中所有与pattern匹配的字符串,对每一个字符串里与组匹配的的字符串组成成一个元组,最后全部组成一个列表,有点像groups(),举个例子就明白了
import re
print(re.findall(r"(\d+)(\w)", "123abc456d"))# [('123', 'a'), ('456', 'd')]
类似的有finditer
,不同点是,其返回的是一个由匹配对象组成的迭代器
compile()
re.compile(pattern, flags=0)
将正则表达式pattern转为模式对象返回
模式对象
模式对象的一些方法,其基本在re模块种也有,用法也差不多
search()
Pattern.search(string[, pos[, endpos]])
- string:要匹配的字符串
- pos:开始位置
- endpos:结束位置
例如
import re
p = re.compile(r"(\d+)\w")
print(p.search("123a456b")[0])# 123a
print(p.search("123a456b",4,8)[0])# 456b
print(p.search("123a456b",6,8)[0])# 6b
spilt()
Pattern.split(string, maxsplit=0)
- string:要分割的字符串
- maxsplit:最大分割次数,为0时表示无穷
类似于字符串的split(),只是变成了将匹配对象作为分隔符,返回分割后的字符串组成的列表,例如
import re
p = re.compile(r"\d+")
strx = p.split("a1b2c123d",2)
for i in strx:
print(i)
# output:
# a
# b
# c123d
sub()
Pattern.sub(repl, string, count=0, flags=0)
repl
:替换成字符串string
:匹配字符串
将匹配字符串中与正则匹配的部分,替换成repl
的字符串
一些细枝末节
正则表达式的匹配默认是匹配第一个尽可能长的字符串(贪婪),在限定修饰符后面加上?可以启用非贪婪模式,匹配第一个尽可能短的字符串,如*?