一.基本使用
1.在python中使用正则表达式
在Python中需要通过正则表达式对字符串进⾏匹配的时候,可以使⽤⼀个python处理文本的标准库,标准库的意思是这是一个python内置模块,不需要额外下载,名字为re
。
re模块的使用:
import re
2.常用元字符
Parameter | Description |
---|---|
. | 匹配任意1个字符(除了\n) |
[] | 匹配[ ]中列举的字符 |
\d | 匹配数字,即0-9,等同于[0-9] |
\D | 匹配非数字,即不是数字 |
\s | 匹配任意的空白符 |
\S | 匹配非任意的空白符 |
\w | 匹配单词字符,即a-z、A-Z、0-9、_ |
\W | 匹配⾮单词字符 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
如果你想匹配没有预定义元字符的字符集合,只需要在方括号里列出它们就行了
e.g.:
# `[0-9]` 等效于`\d`
print(re.match("[0-9]+","10086").group())
print(re.match("\d+","10086").group())
# results: 10086
# 匹配开始与结束,以邮箱为例
print(re.match("^\w+\.\w+@\w+\.\w+$", "Dylan.K@163.com").group())
# results: Dylan.K@163.com
3.字符转义
如果你想查找元字符本身的话,比如你查找.
,或者*
,就出现了问题:你没办法指定它们,因为它们会被解释成别的意思。这时你就得使用\
来取消这些字符的特殊意义。因此,你应该使用\.
和\*
。当然,要查找\
本身,你也得用\\
.
e.g.:
# 用‘\.’ 来表示‘.’
print(re.findall("Throughput\s*(\d+\.?\d*)\s*MB/s", "Throughput 0.472 MB/s"))
# results: ['0.472']
4.常用的限定符
Parameter | Description |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
e.g.:
# 重复n到m次
print(re.match('[\w]{4,10}@\d{3}.com', 'dylan@163.com').group())
# results: dylan@163.com
5.分组匹配
Parameter | Description |
---|---|
| | 匹配左右任意⼀个表达式 |
(ab) | 将括号中字符作为⼀个分组 |
\num | 引⽤分组num匹配到的字符串 |
(?P<name>) | 分组起别名,匹配到的子串组在外部是通过定义的 name 来获取的 |
(?P=name) | 引⽤别名为name分组匹配到的字符串 |
e.g.:
# (163|126|qq) 括号中的表达式作为一个分组
print(re.match('[\w]{4,10}@(163|126|qq).com', 'dylan@163.com').group())
# results: dylan@163.com
二. re.match函数
1.语法介绍
re.match
尝试从字符串的起始位置匹配一个模式,匹配成功 re.match
方法返回一个匹配的对象,否则返回 None。
语法:re.match(pattern, string, flags=0)
Parameter | Description |
---|---|
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等 1.re.I 忽略大小写 2.re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境 3.re.M 多行模式 4.re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符) 5.re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库 6.re.X 为了增加可读性,忽略空格和 # 后面的注释 |
e.g.:
# re.I 忽略大小写
print(re.match('w', 'Www.runoob.com',re.I).group())
# results: W
# 也可以这么写
print(re.match('[wW]', 'Www.runoob.com',re.I).group())
# results: W
# 起始位置匹配不到就会报错
print(re.match('r', 'www.runoob.com').group())
# results: None
# 匹配 r
print(re.match('\w+\.(\w)', 'www.runoob.com').group(1))
# results: r
# re.S 用法
print(re.match('.', '.*%',re.S).group())
# results: .
2.group()和groups()的使用
我们可以使用group()
或groups()
匹配对象函数来获取匹配后的结果。
2.1 group()
group(...)
group([group1, ...]) -> str or tuple.
Return subgroup(s) of the match by indices or names.
For 0 returns the entire match.
获得一个或多个分组截获的字符串;指定多个参数时将以元组形式返回。group1可以使用编号也可以使用别名;编号0代表匹配的整个子串;默认返回group(0);没有截获字符串的组返回None;截获了多次的组返回最后一次截获的子串。
e.g.:
print(re.match("([^.]*)-(\d+)","010-123456789").group())
# results: 010-123456789
print(re.match("([^.]*)-(\d+)","010-123456789").group(1))
# results: 010
print(re.match("([^.]*)-(\d+)","010-123456789").group(2))
# results: 123456789
2.2 groups()
groups(...)
groups([default=None]) -> tuple.
Return a tuple containing all the subgroups of the match, from 1.
The default argument is used for groups
that did not participate in the match
以元组形式返回全部分组截获的字符串。相当于调用group(1,2,…last)。没有截获字符串的组以默认值None代替。
e.g.:
print(re.match("([^.]*)-(\d+)","010-123456789").groups())
# results: ('010', '123456789')
三. re.search函数
re.search 扫描整个字符串并返回第一个成功的匹配,如果没有匹配,就返回一个 None。
re.match与re.search的区别:
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
e.g.:
print(re.search("([-])","010-123456789").group())
# results: - type:str
print(re.search("([-])","010-123456789").groups())
# results: ('-',) type: tuple
四. re.findall函数
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
注意: match
和 search
是匹配一次, findall
匹配所有。
e.g.:
# search 匹配一次,返回str
print(re.search("([\.])","www.google.com").group())
# results: .
# findall 匹配所有,返回list
print(re.findall("\.","www.google.com"))
# results: ['.', '.']
五. re.finditer函数
和 findall
类似,在字符串中找到正则表达式所匹配的所有数据,并把它们作为一个迭代器返回。
print(re.findall("\d+","12ABC32BCD43DEF322"))
# results: ['12', '32', '43', '322']
# finditer 返回迭代器,需要遍历才能获取匹配到的数据
print([i.group() for i in re.finditer("\d+","12ABC32BCD43DEF322")])
# results: ['12', '32', '43', '322']
六. re.sub函数
sub是substitute的所写,表示替换,将匹配到的数据进⾏替换。
1.语法介绍
语法:re.sub(pattern, repl, string, count=0, flags=0)
Parameter | Description | |
---|---|---|
pattern | 必选,表示正则中的模式字符串 | |
repl | 必选,就是replacement,要替换的字符串,也可为一个函数 | |
string | 必选,被替换的那个string字符串 | |
count | 可选参数,count 是要替换的最大次数,必须是非负整数。如果省略这个参数或 | 设为 0,所有的匹配都会被替换 |
flags | 可选参数,标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。 |
2.演示
# 替换后四位为0
print(re.sub('\d{4}$','0000','13549876489'))
# results: 13549870000
六. re.split()函数
函数作用:分割字符串,将字符串用给定的正则表达式匹配的字符串进行分割,分割后返回结果list。
1.语法介绍
split(pattern, string, maxsplit=0, flags=0)
Parameter | Description |
---|---|
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
maxsplit | 分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数 |
flags | 可选参数,标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。 |
2.演示
# 根据 : 和 空格进行分割
print(re.split(r":| ","info:xiaoming 22 shanghai"))
# results: ['info', 'xiaoming', '22', 'shanghai']
七. python贪婪和⾮贪婪
Python⾥数量词默认是贪婪的,总是尝试匹配尽可能多的字符;⾮贪婪则相反,总是尝试匹配尽可能少的字符。
注:我们一般使用非贪婪模式来提取。
在*
,?
,+
,{m,n}
后⾯加上?
,使贪婪变成⾮贪婪。
# “.+”会从字符串的启始处抓取满⾜模式的最⻓字符
print(re.match(".+(\d+-\d+-\d+)","a number 123-456-789").group(1))
# 3-456-789
#⾮贪婪操作符“?”,要求正则匹配的越少越好
print(re.match(".+?(\d+-\d+-\d+)","a number 123-456-789").group(1))
# 123-456-789
正则表达式模式中使⽤到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满⾜匹配最⻓字符串,.+
会从字符串的启始处抓取满⾜模式的最⻓字符,其中包括我们想得到的第⼀个整型字段的中的⼤部分。.+?
要求正则匹配的越少越好,