目录
1.正则表达式
2.re模块函数-findall
3.re模块函数-search
4.re函数模块-sub
总结
正则: 为了匹配一个符合规则的字符串
1.精确匹配:
abc:匹配abc的子串
2.选择性匹配:
red|blue|green:匹配red 或 blue 或green
3.中括号[]:一个[]只匹配1位,[^]:排除
[0-9]:匹配0-9之间的一个数字
[^0-9]:排除0-9
[a-z] :小写字母
[A-Z]:大写字母
[A-z]:大小写字母 和 _
[0-9A-z]:字母数字和 _
[\u4e00-\u9fa5]: 匹配所有汉字
4.元字符: 大小写反义
\d:[0-9]
\D:[^0-9]
\w:[0-9A-z]
\W:[^0-9A-z]
.:代表任意字符, \n除外
[\d\D]:代表一切字符
\s:空白字符
\S:非空白字符
\b:匹配单词边界。
\B:匹配非单词边界。
5.量词: 0代表匹配空格
re? 或 re{0,1}:0-1
re* 或 re{0}:0-多
re+ 或 re{1,}:1-多
re{n}: n位
re{m,n}: m-n
re{m,}: m-多
6.贪婪匹配: 能匹配多,不匹配少 例如,\d{2,4}, 以匹配4个为主
非贪婪匹配:量词后加? 能匹配少,不匹配多 例如,\d{2,4}?, 以匹配2个为主
7.分组,将字符串内容按照部分分组匹配
分组:() ,几个() 就有几组
命名捕获分组: (?P
非捕获分组: (?:rex) : 取消分组
反向引用: \num, 反向引用第num组的内容
例如:
AABB (\w)\1(\w)\2
ABAB (\w)(\w)\1\2
8.限定符
^: 以....开头
$: 以....结尾
9. 断言:
正向断言,正则在前,条件在后
反向断言: 条件在前,正则在后
正向确定断言:rex(?=\d+) 提取后面是数字的rex
正向否定断言:rex(?!\d+) 提取后面不是数字的rex
反向确定断言:(?<=window)\d+ 提取前面是window的数字
反向否定断言:(? (?=.*rex):某个字符串必须包含rex
# 手机号 ^1[3-9]\d{9}$
# 10-12 ^1[0-2]$
# 0-12 ^(\d|1[0-2])$
0-9 \d
10-12 1[0-2]
# 0-255 ^(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$
0-9 \d
10-99 [1-9]\d
100-199 1\d{2}
200-249 2[0-4]\d
250-255 25[0-5]
# 匹配 ipv4地址 0-255.0-255.0-255.0-255
^(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])(\.(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])){3}$
# 必须有大写字母 小写字母 数字 6-8位
^(?=.*\d)(?=.*[A-Z])(?=.*[a-z])[A-Za-z0-9]{6,8}$
findall(pattern,string,flag)
如果没有分组:返回匹配子串组成的列表
如果有一个分组:只返回分组结果组成的列表
如果有多个分组:返回分组元祖组成的列表
总结:
如果有分组,findall只返回分组结果
import re
s = '17788189248'
res = re.findall(r'(\d{3})(\d{4})\d{4}', s)
print(res)
# 提取身份证号的 出生年 月 日
s = '41072419980815451x'
res = re.findall(r'\d{6}(\d{4})(\d{2})(\d{2})', s)
print(res[0]) # ('1998', '08', '15')
# 30岁,25个 ,95年=》30,25,95
s = '30岁,25个 ,95年'
res = re.findall(r'\d+', s)
print(res)
'''
假设我们有一些’[email protected]'格式的电子邮件地址,
请编写程序打印给定电子邮件地址的用户名,用户名和公司名都只由字母组成
如果下面的电子邮件地址作为程序的输入:[email protected].
那么程序的输出应该是:john
'''
s = '[email protected]'
res = re.findall(r'(\w+)@', s)
print(res)
'''
insert into tb_user(name, sex, age)
values ( #{name} , #{sex} , #{age} )
提取 #{name} , #{sex} , #{age}
'''
s = 'insert into tb_user(name, sex, age) values ( #{name} , #{sex} , #{age} )'
res = re.findall(r'#{\w+}', s)
print(res)
search(pattern, string,flag)
search:匹配符合条件第一个子串和首尾下标,
返回match对象,找不到返回None
index(''):返回第一个下标,找不到报错
find(''):返回第一个下标,找不到-1
import re
s = 'a12b23'
res = re.search(r'\d{2}', s)
print(res)
'''
finditer:匹配符合条件所有子串,返回迭代器
迭代器中每一个元素是match对象
'''
s = 'a12b23'
res = re.finditer(r'\d{2}', s)
for r in res:
print(r.group())
import re
# 替换所有数字为#
s = 'he12llow wo34rld11'
res = re.sub(r'\d+', '+', s)
print(res) # he+llow wo+rld+
# 手机号脱敏
s = '17788189248'
res = re.sub(r'(\d{3})\d{4}(\d{4})', r'\1****\2', s)
print(res) # 177****9248
# 邮箱号脱敏
s = '[email protected]'
res = re.sub(r'(..).+(@.+)', r'\1*******\2', s)
print(res) # 56*******@qq.com
# 将所有数字反转替换
s = 'he123llow wo456rld'
res = re.sub(r'\d+', lambda x: (x.group())[::-1], s)
print(res) #he321llow wo654rld
s = 'he12llow wo34rld11'
res = re.subn(r'\d+', '#', s)
print(res) # ('he#llow wo#rld#', 3)
s = 'hello11world22xx'
res = re.split(r'\d+', s)
print(res) # ['hello', 'world', 'xx']
match(pattern,string,flags):以pattern开头,返回match对象
fullmatch(pattern,string,flags):以pattern开头,以pattern结尾,返回match对象
finditer(pattern,string,flags): 符合pattern的所有结果,返回迭代器,迭代器的元素放的是match对象
search(pattern,string,flags):符合pattern的第一个数据,,返回match对象
findall(pattern,string,flags):
没有分组: 返回所有匹配结果组成的列表
如果有1个分组: 只返回这1个分组结果组成的列表
如果有多个分组: 只返回多个分组结果元组组成的列表
sub(pattern,repl,string,count,flags):
返回替换后的结果
pattern:被替换的正则
repl:
要替换的正则或字符串或lamda,lamda 参数为匹配结果
如果使用反向引用,必须 使用 r'\1***\2'
count:替换个数
subn(pattern,repl,string,count,flags):
返回替换后的结果和替换个数 组成的元组
re.split(pattern,string,maxsplit,flags)
按照pattern拆分,返回拆分后的列表
字符串替换:
replace(old,new,string,count)
old:被替换的子串
new:要替换的字串
count:替换的个数