正则表达式
- 什么是正则表达式
正则表达式是一种处理字符串的工具
- 正则表达式语法(通用)
fullmatch(正则表达式,字符串) –判断正则表达式和字符串是否完全匹配,如果不能就返回None
a. 普通字符
除了在正则中有特殊功能和特殊意义的字符以外的字符就是普通字符。
普通字符在正则表达式中表示这个字符本身
re_str=r'abc'
print(fullmatch(re_str,'1abc')) #None
b. . –匹配一个任意字符
re_str=r'.bc' #匹配一个长度是3的字符串,后俩个字符是bc,第一个字符是任意字符
print(fullmatch(re_str,'1bc')) #<_sre.SRE_Match object; span=(0, 3), match='1bc'>
print(fullmatch(re_str,'bc')) #None
c. \w –匹配任意一个数字,字母,下划线(在ASCII码表中)
re_str=r'\w123'
print(fullmatch(re_str,'9123')) #<_sre.SRE_Match object; span=(0, 4), match='9123'>
print(fullmatch(re_str,'+123')) #None
# 注意:\w 可以匹配任意非ASCII中的字符
d. \d –匹配任意一个数字字符
re_str=r'\d\dabc'
print(fullmatch(re_str,'90abc')) #<_sre.SRE_Match object; span=(0, 5), match='90abc'>
e. \s –匹配任意一个空白字符
# 常见的空白字符:' ','\n' ,'\t'
re_str=r'\d\d\s\d'
print(fullmatch(re_str,'12 4')) #<_sre.SRE_Match object; span=(0, 4), match='12 4'>
f. \大写字母(\W,\S,\D)
# \大写字母 的功能和 \小写字母 的功能相反
# \S --匹配任意一个非空白字符
# \D --匹配任意一个非数字字符
# \W --匹配任意一个非数字,字母,下划线
g. [字符集] –匹配字符集中的任意一个字符
# [字符1-字符2]中俩个字符之间的范围,字符1的编码值比字符2的编码值小
# 注意:一个[]只能匹配一个字符
# [a-z] -匹配任意一个小写字母
# [A-Z] -匹配任意一个大写字母
# [a-zA-Z] -匹配任意一个字母
# [\u4e00-\u9fa5] -匹配任意一个中文字符
re_str=r'abc[1234]'
print(fullmatch(re_str,'abc3')) #<_sre.SRE_Match object; span=(0, 4), match='abc3'>
h. [^字符集] -任意一个不在字符集中的字符
re_str=f'[^asdfg]1234'
print(fullmatch(re_str,'v1234')) #<_sre.SRE_Match object; span=(0, 5), match='v1234'>
# 注意: # a. []中的^只有在在前面的时候才有特殊意义,在其他位置的时候表示字符^本身 # b. []中的-只有在在俩个字符之间的时候才有特殊意义,在其他位置的时候表示字符-本身
匹配次数
1)* –匹配0次或多次
a* --a匹配0次或多次
\d* --任意数字出现0次或者多次
[abc]* --[abc]匹配0次或多次
re_str=r'[123]*abc'
print(fullmatch(re_str,'123abc')) #<_sre.SRE_Match object; span=(0, 6), match='123abc'>
print(fullmatch(re_str,'136abc')) #None
-
- –匹配一次或多次
re_str=r'[123]+abc'
print(fullmatch(re_str,'123abc')) #<_sre.SRE_Match object; span=(0, 6), match='123abc'>
3) ? –匹配0次或1次
re_str=r'm?abc'
print(fullmatch(re_str,'abc')) #<_sre.SRE_Match object; span=(0, 3), match='abc'>
- {} –匹配
{N} --匹配n次
{m,n} --匹配m到n次
{m,} --匹配至少m次
{,n} --匹配最多n次
re_str=r'\d{3}abc'
print(fullmatch(re_str,'abc')) #None
print(fullmatch(re_str,'123abc')) #<_sre.SRE_Match object; span=(0, 6), match='123abc'>
贪婪和非贪婪
当匹配次数不确定的时候,匹配的模式分为贪婪和非贪婪俩种
贪婪:在能匹配成功的前提下,次数尽可能多的匹配(默认是贪婪模式)
非贪婪:在能匹配成功的前提下,次数尽可能少的匹配,在不确定匹配次数后加?就是非贪婪
(*?,=?,{m,n}?,{m,}?,{,n}?)
re_str=r'.*abc'
print(fullmatch(re_str,'adabcfabc')) #<_sre.SRE_Match object; span=(0, 9), match='adabcfabc'>
- search
re_str=r'\d\d'
print(search(re_str,'adf45dfg89'))
#<_sre.SRE_Match object; span=(3, 5), match='45'>
print(search(r'.*abc','你好920abc=====niabcdff'))
#<_sre.SRE_Match object; span=(0, 18), match='你好920abc=====niabc'>
print(search(r'.*?abc','你好920abc=====niabcdff'))
#<_sre.SRE_Match object; span=(0, 8), match='你好920abc'>
- findall
print(findall(r'a\d+','sdfsafa45436357gfshffs')) #['a45436357']
print(findall(r'a\d+?','sdfsafa45436357gfshffs')) #['a4']
检测符号
检测类的符号只做字符的检测不会进行匹配
1)\b – 检测是否是单词边界(单词边界就是任意可以区分俩个不同单词的符号。比如:空白字符,标点符号,字符串开头和字符串结尾)
re_str=r'abc\b123' #re_str='abc123'
print(fullmatch(re_str,'abc 123')) #None
print(fullmatch(re_str,'abc123')) #None
re_str=r'abc,\b123' #re_str='abc,123'
print(fullmatch(re_str,'abc,123')) #<_sre.SRE_Match object; span=(0, 7), match='abc,123'>
re_str=r'\b\d{3}\b'
print(findall(re_str,',234,d你好吗,345,辅导费')) #['234', '345']
2)^ –检测是否是字符串开头
re_str=r'^\d{3}'
print(findall(re_str,'jnonon,234,566,sfdf,678')) #[]
print(findall(re_str,'345jnonon,234,566,sfdf,678')) #['345']
3)$ –检测是否是字符串结尾
re_str=r'\d{3}$'
print(findall(re_str,'sdfdsf678')) #['678']
分支 –|
| –在正则中表示或者
正则表达式1|正则表达式2|正则表达式3| … –让字符串先和第一个正则匹配,如果失败,就和正则2匹配,以此类推
# 写一个正则能够匹配3个数字或者3个字母
re_str='\d{3}|[a-zA-Z]{3}'
print(fullmatch(re_str,'234')) #<_sre.SRE_Match object; span=(0, 3), match='234'>
# 练习:写一个正则匹配的是:abc后面是三个数字或者俩个大写字母
re_str=r'abc\d{3}|abc[A-Z]{2}'
# re_str=r'abc(\d{3}|[A-Z]{2})'
print(fullmatch(re_str,'abc123')) #<_sre.SRE_Match object; span=(0, 6), match='abc123'>
print(fullmatch(re_str,'abcAa')) #None
分组 –()
1)把正则的部分内容看成一个整体,进行操作
#例子:能够匹配一个字符串是俩个数字三个字母这种结构不断重复的字符串
re_str=r'(\d{2}[a-zA-Z]{3})+'
print(fullmatch(re_str,'88dff00adf87asd')) #<_sre.SRE_Match object; span=(0, 15), match='88dff00adf87asd'>
2)分组和\N配合使用来匹配内容重复
re_str=r'abc(\d{2})=\1'
print(fullmatch(re_str,'abc78=78')) #<_sre.SRE_Match object; span=(0, 8), match='abc78=78'>
print(fullmatch(re_str,'abc78=77')) #None
re_str=r'abc(\d{2})h(\d{2})=\2'
print(fullmatch(re_str,'abc78h90=90')) #<_sre.SRE_Match object; span=(0, 11), match='abc78h90=90'>
re_str=r'(a(\d{2}))\1=\2'
print(fullmatch(re_str,'a34a34=34')) #<_sre.SRE_Match object; span=(0, 9), match='a34a34=34'>
re模块
- compile(正则表达式) –编译正则表达式创建一个正则表达式对象匹配;
import re
re_obj=re.compile(r'\d{3}')
# re.fullmatch(正则表达式,字符串)
# 正则对象.fullmatch(字符串)
print(re_obj.fullmatch('799')) #<_sre.SRE_Match object; span=(0, 3), match='799'>
- 匹配
1)fullmatch(正则表达式,字符串) –完全匹配,查看整个字符串和正则表达式;匹配成功返回对象,失败返回None
2)match(正则表达式,字符串) –匹配字符串开头;匹配成功返回对象,失败返回None
re_obj=re.compile(r'\d{3}')
print(re_obj.match('799返回的')) #<_sre.SRE_Match object; span=(0, 3), match='799'>
3)匹配对象(match对象)
re_str=r'(\d{3})[a-z]{2}'
result=re.fullmatch(re_str,'234kl')
print(result) #<_sre.SRE_Match object; span=(0, 5), match='234kl'>
a. 获取匹配到的字符串
# 匹配对象.group() --获取整个正则匹配到的结果
# 匹配对象.group(N) --获取正则中第N个分组匹配到的结果
print(result.group()) #234kl
print(result.group(1)) #234
b. 获取匹配到的字符串在原字符串中的位置
print(result.span()) #(0, 5)
print(result.span(1)) #(0, 3)
c.获取原字符串
print(result.string) #234kl
- 查找
1)search(正则表达式,字符串) –在字符串中获取第一个满足正则表达式的子串,如果找到了返回匹配对象,找不到返回None
re_str=r'\d{3}'
print(re.fullmatch(re_str,'4345dfafdf'))
2)findall(正则表达式,字符串) –获取字符串中所有满足正则的子串,返回的是一个列表,列表的元素就是匹配到的结果
a. 正则中没有结果 --列表中的元素就是整个正则表达式匹配到的子串
re_str=r'\d{3}[A-Z]{2}'
str1='你好234KL6789OP'
result=re.findall(re_str,str1)
print(result) #['234KL', '789OP']
# b. 正则中有一个分组 --匹配成功后将分组匹配到的子串作为列表元素
re_str=r'(\d{3})[A-Z]{2}'
str1='你好234KL6789OP'
result=re.findall(re_str,str1)
print(result) #['234', '789']
# c. 正则中有多个分组 --匹配成功后每个匹配结果是一个元组,元组中的元素是每个分组匹配到的内容,将元组作为列表的元素
re_str=r'(\d{2}-([A-Z]{2}))'
str1='23-KLB你好大方电饭锅89-LL'
result=re.findall(re_str,str1)
print(result) #[('23-KL', 'KL'), ('89-LL', 'LL')]
3)finditer(正则表达式,字符串) –获取字符串中所有满足正则的子串;返回的是一个迭代器,迭代器中的元素是匹配对象
re_str=r'(\d{2}-([A-Z]{2}))'
str1='23-KLB你好大方电饭锅89-LL'
result=re.finditer(re_str,str1)
print(result) #<callable_iterator object at 0x038D4ED0>
print(list(result))
4)字符串替换
# 将字符串中所有数字字符都替换成'+'
# sub(正则表达式,新字符串,原字符串) --将原字符串中所有满足正则表达式的子串全部替换成新字符串
str1='大街上的12314咖啡店发34南大道辅导费567大方的第三'
result=re.sub(r'\d','+',str1)
print(result) #大街上的+++++咖啡店发++南大道辅导费+++大方的第三
str1='大街上的12314咖啡店发34南大道辅导费567大方的第三'
result=re.sub(r'\d+','+',str1)
print(result) #大街上的+咖啡店发+南大道辅导费+大方的第三
# 替换语句中的不良文字
sentence='你丫是傻叉吗? 我操你大爷的. Fuck you'
result=re.sub(r'操|fuck|傻叉','*',sentence,flags=re.IGNORECASE)
print(result)
5)字符串切割
# split(正则表达式,字符串) --将字符串中满足正则表达式的子串作为切割点对字符串切割
poem='床上明月光,疑是地上霜。举头望明月,低头思故乡。'
result=re.split(r'[,。]',poem)
print(result)
忽略大小写和多行匹配
- 忽略大小写:在正则表达式最前面加上(?i)
from re import fullmatch,IGNORECASE
re_str=r'(?i)abc'
print(fullmatch(re_str,'ABC')) #<_sre.SRE_Match object; span=(0, 3), match='ABC'>
- 单行匹配:.能匹配换行符的匹配模式,在正则的最前面加(?s)
# 默认是多行匹配 .不能匹配换行符
re_str=r'a.+b'
print(fullmatch(re_str,'a+\nb')) #None
re_str=r'(?s)a.+b'
print(fullmatch(re_str,'a+\nb')) #<_sre.SRE_Match object; span=(0, 4), match='a+\nb'>
- 符号的转义
# 在正则中有特殊功能特殊意义的符号前加\,让其功能消失,表示本身
re_str=r'\d\d\.\d\d'
print(fullmatch(re_str,'30.45')) #<_sre.SRE_Match object; span=(0, 5), match='30.45'>
独立存在有特殊功能的符号,在[]中功能会直接消失
re_str=r'[=a.]123'
print(fullmatch(re_str,'.123')) #<_sre.SRE_Match object; span=(0, 4), match='.123'>
print(fullmatch(re_str,'5123')) #None