20220614 正则学习总结
一、认识正则
1.什么是正则表达式
正则表达式是一个可以让复杂字符串问题变得的简单的工具
1)验证输入的数据是否是一个合法的手机号
tel = input('请输入手机号')
if len(tel) != 11:
print('不是手机号')
else:
if tel.isdigit():
if tel[0] != '1':
print('不是手机号')
else:
if tel[1] in '012':
print('是手机号')
else:
print('不是手机号')
tel = input('请输入手机号')
result = fullmatch(r'1[3-9]\{9}', tel)
if result:
print('是手机号')
else:
print('不是手机号')
2)提取字符串中所有的数字字串
str1 = '数据3637元环境涉及09333对的8.95'
二、正则匹配符号
fullmatch(正则表达式, 字符串) - 判断正则表达式和指定的字符串进行完全匹配(判断整个字符串是否符合正则表达式所描述的规则)
正则表达式 - python中用字符串(带r的字符串)来表示一个正则表达式
1.普通字符
在正则表达式中表示符号本身的字符就是普通字符
result = fullmatch(r'abc','abc')
print(result)
- ‘.’ - 匹配任意一个字符
result = fullmatch(r'a.c','a c')
- ‘\d’ - 匹配任意一个数字
result = fullmatch(r'a\d\dc','a22c')
print(result)
- ‘\s’ - 匹配任意一个空白字符
空白字符 - 可以匹配空白效果的字符,包括:空格,回车(\n),水平制表符(\t)
result = fullmatch(r'a\sc', 'a\tc')
print(result)
- ‘’\w’ - 匹配任意一个数字,字母,下划线或者中文
result = fullmatch(r'\wc', 'a啊c')
print(result)
- ‘\D’ ‘\S’ ‘\W’ - 与小写功能的相反
result = fullmatch(r'a\Dc', 'a-c')
print(result)
result = fullmatch(r'a\Sc', 'aQc')
print(result)
result = fullmatch(r'\wc', 'a+c')
print(result)
7.[字符集] - 匹配在字符集中的任意一个字符
用法一:中括号中直接写多个普通字符[ma1,]
用法二:中括号中包含反斜杠开头的特殊符号[ma,\d]
用法三:中括号中减号放在两个字符之间表示范围[1-7]
注意:[]中-表示两个字符之间才表示从谁到谁,并且减号前面的字符的编码值必须小于减号后面的字符的编码值
[]中-如果不在两个字符之间,-就是一个普通符号,表示符号本身
8.[^字符集] - 匹配任意一个不在字符集中的任意一个字符
result = fullmatch(r'a[^MNCX]c','aPc')
print(result)
\d ==[0-9]
\D == [^0-9]
\s == [ \n\t]
\S == [^ \n\t]
\w == [a-zA-Z0-9_\4e00- \u9fa5]
注意:[]中,如果不在最前面,就表示这个符号本身
三、政策匹配次数
1.+ - 匹配1次或者多次(至少一次)
匹配符号 +
result = fullmatch(r'a+b','aaaaaaaaaaaaaaab')
print(result)
result = fullmatch(r'\d+b','2321312112213232b')
print(result)
result = fullmatch(r'[MNI1-6]+b','3MINININIb')
print(result)
2.* - 匹配0次或者多次(匹配任意次数)
result = fullmatch(r'a*b','aaaaaaaaaab')
print(result)
result = fullmatch(r'a*b','b')
print(result)
3.? - 匹配0次或者1次
result = fullmatch(r'\d?b','2b')
print(result)
result = fullmatch(r'\d?b','b')
print(result)
{}
‘’’
{N} - N次
{M,N} - M到N次
{M,} - 至少M次
{,N} - 最多N次
result = fullmatch(r'a{3}b','aaab')
print(result)
result = fullmatch(r'a{2,5}b','aaaab')
print(result)
result = fullmatch(r'a{5,}b','aaaaaaaaab')
print(result)
result = fullmatch(r'a{,5}b','aaaab')
print(result)
练习:写一个正则可以匹配任意一个整数字符串
#‘1923’、‘-234’、‘+234’、‘2’、‘-2’ 、 - 合法
#‘agg2’、‘23.23’ ‘001’ - 不合法
#0 不考虑
result = fullmatch(r'[-+]?[1-9]{1}[0-9]{0,}','-234')
if result:
print('合法!')
else:
print('不合法!')
练习2:写一个正则表达式匹配一个变量名,变量名要求:由数字、字母下划线组成,数字不能开头
result = fullmatch(r'[a-zA-Z_][a-zA-Z_\d]*','asda')
if result:
print('合法!')
else:
print('不合法!'
四、贪婪和非贪婪
‘’’
fullmatch(正则,字符串) - 完全匹配
match(正则,字符串) - 匹配字符串开头
search(正则,字符串) - 匹配字符串第一个满足正则的字符串
findall(正则,字符串) - 获取字符串中所有满足正则的子串
sub(正则,字符串1.字符串2) - 将字符串2中所有满足正则的子串都替换成字符串1
split(正则,字符串) - 将字符串中所有满足正则字符串作为切割点对字符串进行切割
‘’’
1.贪婪和非贪婪
from re import *
‘’’
在匹配次数不确定的情况下,匹配模式分为贪婪和非贪婪两种
1)贪婪 - 在能匹配成功的前提下,如果有多种次数都能匹配成功,取最大次数
+、*、?、{m,n}、{M,} 、{,N}
2)非贪婪 - 在能匹配成功的前提下,如果有多种次数都能匹配成功,取最小次数
+?、*?、??、{m,n}?、{M,}? 、{,N}?
‘’’
#2 -> amnb
#6-> amnb数据复b
#9-> amnb数据复baab
result = match(r'a.+b', 'amnb数据复baab计算机')
print(result)
result = match(r'a.+?b', 'amnb数据复baab计算机')
print(result)
五、分组和分支
1.分组:()
一个()就是一个分组
1)整体控制 - 将正则中需要看成一个整体来控制次数的地方用()括起来,作为一个发呢组
2)重复 - 在正则中可以通过\M来重复它前面第M个分组匹配到的结果
3)捕获 - 获取指定分组中的匹配结果(findall会自动捕获分组内容)
案例一:匹配:两个数字两个大写字母的结构重复三次:12MJ12KJ31JK
#方法一:
result = fullmatch(r'\d\d[A-Z]{2}\d\d[A-Z]{2}\d\d[A-Z]{2}','12MJ12KJ31JK')
print(result)
#方法二:
result = fullmatch(r'(\d\d[A-Z]{2}){3}','12MJ12KJ31JK')
print(result)
案例二:匹配:‘23a23’,‘99a99’,‘80a80’
result = fullmatch(r'(\d\d)a\1','80a80')
print(result)
result = fullmatch(r'(\d\d)a(\d\d)a\1','78a78a78')
print(result)
result = findall(r'\d+','哈2723环境数据29jjj')
print(result)#['2723', '29']
result = findall(r'[\u4e00-\u9fa5]\d+','哈2723环境数据29jjj')
print(result)#['哈2723', '据29']
result = findall(r'[\u4e00-\u9fa5]{2}\d+','哈2723环境数据29jjj')
print(result)#['数据29']
result = findall(r'[\u4e00-\u9fa5]{2}(\d+)','哈2723环境数据29jjj')
print(result)#['29']
2.分支 -
正则1|正则2 - 字符串如果可以和两个正则中的任意一个匹配成功则匹配成功,两个都不能匹配就匹配失败
result = fullmatch(r'abc\d{3}|[A-Z]{2}','abc341')
print(result)
result = fullmatch(r'abc(\d{3}|[A-Z]{2})','abc341')
print(result)
六、检测类符号
检测类符号的工作原理:先匹配,在匹配成功之后在检测检测类符号所在的位置是否符合相关要求。
1.\b - 检测\b所在的位置是否是单词边界
单词边界:空白符号、英文的标点符号,字符串开头和字符串结尾
result = fullmatch(r'm\b.n','m\'n')
print(result)
result = findall(r'\b\d+','881gdgfd,554sffe66sffsdfs44/2fsfds22 00esfd')
print(result)#['881', '554', '2', '00']
2.^ - 检测是否是字符串开头
3.$ - 检测是否是字符串结尾
判断一个字符串是否以三个数字结尾
result = search(r'\d{3}$','asdas321355!sasa1542/sa5123daasd1234')
print(result)
七、转义符号
1.转义符号 - 在本身具备特殊意义或者特殊功能的符号前加上一个\,变成一个普通符号
result = fullmatch(r'\d\.+\d','1.3')
print(result)
在[]外面独立存在有特殊意义的符号,在[]里面会自动变成普通符号,例如. + * ? $