正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。
例如:如何判断一个字符串是不是手机号(检测用户填写)
17611105750
11位;数字组成不能包含其他字符;1开头;第二位是3,4,5,7,8
如何将以上规则描述出来,让计算机可以识别,就是正则表达式要完成的工作
Python中需要通过正则表达式对字符串进⾏匹配的时候, 使⽤re模块
re 模块是Python当中提供的正则表达式工具包,使 Python 语言拥有全部的正则表达式功能
import re
match(匹配):re.match尝试从字符串的起始位置匹配一个模式
re.match(正则表达式,要匹配的字符串)
从左向右开始匹配,如果正则表达式与字符串规则匹配,则返回匹配对象,否则返回None
匹配对象里的group()用来返回字符串中匹配的数据
如:
import re line = “qwertyuiop“ #不具备通用性 s = "qwertyuiopl" print(re.match(line, s).group()) # 输出结果是匹配的部分 qwertyuiop
表示字符
字符
|
功能
|
.
|
匹配任意1个字符(除了
)
|
[ ]
|
匹配[ ]中列举的字符 [^ ]对【】当中的字符取反
|
d
|
匹配数字, 即0-9
|
D
|
匹配⾮数字, 即不是数字
|
s
|
匹配空⽩, 即 空格 ,tab键 ,换行
|
S
|
匹配⾮空⽩
|
w
|
匹配单词字符, 即a-z、 A-Z、 0-9、 _
|
W
|
匹配⾮单词字符
|
中括号[ ],括号括住的就是搜索目标,指定范围,只能取自于它们
[abc]:搜索目标是a、b、c,三个
[a-c]:同样搜索目标是a、b、c
[^0-9] :[]里的^表示非字符,搜索目标非数字字符
表示数量
字符
|
功能
|
*
|
匹配前⼀个字符出现0次或者⽆限次, 即可有可⽆ d*
|
+
|
匹配前⼀个字符出现1次或者⽆限次, 即⾄少有1次
|
?
|
匹配前⼀个字符出现1次或者0次, 即要么有1次, 要么没有
|
{m}
|
匹配前⼀个字符出现m次
|
{m,}
|
匹配前⼀个字符⾄少出现m次 范围信息 m-无限次
|
{m,n}
|
匹配前⼀个字符出现从m到n次范围信息 m-n (可以替代*+?)
|
规定{ }里面写想匹配的次数,也可以用各种规定的符号。
*:匹配表达式任意次数
+:匹配表达式一次或多次
?:匹配表达式零次或一次
{整数}:匹配目标整数次
{整数,}:匹配目标至少整数次
{整数a,整数b}:匹配目标在a到b次之间
ret = re.match("[A-Z][a-z]*","Aabcdef") # 匹配第一个大写字符,后面是小写字符 ret.group() # 输出结果 'Aabcdef'
8到20位的密码, 可以是⼤⼩写英⽂字⺟、 数字、 下划线 ret = re.match("[a-zA-Z0-9_]{8,20}","1ad12f23s34455ff66") ret.group()
表示边界
字符
|
功能
|
^
|
匹配字符串开头 (必须以某个条件开头)
|
$
|
匹配字符串结尾 (必须以某个条件结尾)
|
|
匹配⼀个单词的边界(需要加r)
|
B
|
匹配⾮单词边界
|
两个符号^和$
^:必须从开始匹配,否则匹配失败
$:必须从结尾开始匹配,否则匹配失败
print(re.match('^The', 'The end').group()) 匹配以The开头的字符串
print(re.match('w*send$', 'The end').group()) 匹配必须以end结尾
匹配手机号 re.match("^1[34578]d{9}$", "17611105750")
正则表达式⾥使⽤“”作为转义字符
f:换页符
:换行符
:回车符
:tab制表符
由于正则表达式使用反斜杠来转义特殊字符,而python自身处理字符串时,反斜杠也是用于转义字符,这样就产生了一个双重转换的问题。这个时候我们可以在字符串前加r
Python中字符串前⾯加上 r 表示原始字符串(真实字符串)
'r'是防止字符转义的,如果路径中出现' '的话 不加r的话 就会被转义 而加了'r'之后' '就能保留原有的样子,所以在正则表达式字符串前面加r,表示匹配换行符。
s = r' a' # r 将字符串转换成原始字符串 print(s) # 输出结果为 a 字符 没有被转义
匹配分组
字符
|
功能
|
|
|
匹配左右任意⼀个表达式 (左或右)
|
(ab)
|
将括号中字符作为⼀个分组
|
um
|
引⽤分组num匹配到的字符串
|
(?P<name>)
|
分组起别名
|
(?P=name)
|
引⽤别名为name分组匹配到的字符串
|
“|”:将两个匹配条件进行逻辑或运算
():用括号括住正则表达式,最后得到的匹配结果自动把括号内匹配的内容给分组。
‘1’:用法和()搭配,1对应第一个(),2对应第二个(),且1代表的必须和()里面的内容完全一样。
分组就是用一对圆括号“()”括起来的正则表达式,匹配出的内容就表示一个分组。从正则表达式的左边开始看,看到的第一个左括号“(”表示第一个分组,第二个表示第二个分组,依次类推,需要注意的是,有一个隐含的全局分组(0),就是整个正则表达式。
分完组以后,要想获得某个分组的内容,直接使用group(num)和groups()函数提取
匹配1-100之间的数字: ret = re.match(‘[1-9]d?$|0$|100$',“8") print(ret.group()) # [1-9]第一个数字匹配1-9,第二个数字匹配 d?$ 0$ 100$ 三者任意一个表达式
ret = re.match("w{4,20}@163.com", "test@163.com") ret = re.match("w{4,20}@(163|126|qq).com", "test@126.com") ret = re.match("w{4,20}@(163|126|qq).com", "test@qq.com")
ret = re.match("([^-]*)-(d+)","010-12345678") ret.group() #'010-12345678' ret.group(1) #'010' ret.group(2) #'12345678' ret.groups() # ('010', '12345678')
re模块的其它用法
search 搜索符合特征的字符串
ret = re.search(r"d+", "阅读次数为 9999")ret.group()
findall 找出所有符合特征的字符串
ret = re.findall(r"d+", "python = 9999, c = 7890, c++ = 12345")print(ret)
sub 将匹配到的数据进⾏替换,返回替换后的字符串
ret = re.sub(r"d+", '998', "python = 997") print(ret)
split 根据匹配进⾏切割字符串, 并返回⼀个列表
ret = re.split(r":| ","info:xiaoZhang 33 shandong")