day17学习总结:
1. 认识正则
-
正则表达式:一种让一些复杂的字符串问题变得简单的工具。它并不是Python特有的语法(所有的高级语言都支持正则,正则的语法通用)。不管通过正则表达式解决的是什么问题,写正则表达式的时候都是在使用正则表达式描述字符串规则。
-
示例:判断指定的字符串是否是一个合法的手机号
tel = input('请输入手机号:') def is_tel(tel:str): from re import fullmatch return bool(fullmatch(r'1[3-9]\d{9}',tel)) print(is_tel(tel))
2. 匹配类符号
- 匹配类符号
-
普通符号 - 在正则表达式表示符号本身的符号
# 1)普通符号 - 在正则表达式表示符号本身的符号 result = fullmatch(r'abc','abc') print(result)
-
. - 匹配任意一个字符
result = fullmatch(r'..abc','2#abc') print(result)
-
\d - 匹配人任意一个数字字符
# \d - 匹配人任意一个数字字符 result = fullmatch(r'a\dc','a3c') print(result)
-
\s - 匹配任意一个空白字符
-
空白字符 - 能产生空白效果的字符,如:空格,换行,水平制表符
# \s - 匹配任意一个空白字符 result = fullmatch(r'a\sc','a c') print(result) result = fullmatch(r'\d\d\s.ab','45 %ab') print(result)
-
-
\D - 匹配任意一个非数字字符
# \D - 匹配任意一个非数字字符 result = fullmatch(r'a\Dc','a&c') print(result)
-
\S - 匹配任意一个非空白字符
# \S - 匹配任意一个非空白字符 result = fullmatch(r'a\Sc','abc') print(result)
-
[字符集] - 匹配字符集中的任意一个字符
-
[abc] - 匹配a或者b或者c
-
[abc\d] - 匹配a或者b或者c或者任意一个数字
-
[2-9] - 匹配1~9中的任意一个数字
-
[a-z] - 匹配a~z中的任意小写字母
-
[A-Z] - 匹配A~Z中的任意大写字母
-
[a-zA-Z] - 匹配任意一个字母
-
[a-zA-Z\d~] - 匹配任意一个字母,任意一个数字,或者~
-
[\u4e00-\u9fa5] - 匹配任意一个中文字符
result = fullmatch(r'a[vbnm]c','avc') print(result) result = fullmatch(r's[gmA-Z\d]s','sgs') print(result)
-
-
[^字符集] - 匹配任意一个不在该字符集的
result = fullmatch(r'a[^12a-z]','a3') print(result)
-
3. 匹配次数
-
* - 0次或者多次(任意次数)
-
注意:*号在谁的后面。控制的就是谁的次数
-
a* - 0个或者多个a
result = fullmatch(r'abc*1230','abcccc1230') print(result) result = fullmatch(r'a\d*cd','a555cd') print(result) result = fullmatch(r'c[mn]*ab','cmmmab') print(result)
-
-
+ - 一次或者多次(至少一次)
result = fullmatch(r'a+bc','aaabc') print(result)
-
? - 0次或者1次
result = fullmatch(r'q?abc','abc') print(result)
-
{}
-
{M,N} - M到N次
-
{M,} - 至少M次
-
{,N} - 至多N次
-
{N} - N次
result = fullmatch(r'[mn]{2,4}ab','mmmab') print(result) result = fullmatch(r'[mn]{2,}ab','mmmmmab') print(result) result = fullmatch(r'[mn]{,2}ab','mmab') print(result) result = fullmatch(r'[mn]{3}ab','mmmab') print(result)
-
举例:判断QQ号是否合法,5~12位,不以0开头
num = input('请输入QQ号:') def is_qq(num:str): return bool(fullmatch(r'[1-9]\d{4,11}',num)) print(is_qq(num))
4. 贪婪和非贪婪
-
match(正则表达式,字符串) - 判断字符串开头是否符合正则表达式描述的规则
-
当匹配次数不确定的时候(*,+,?,{M,N},{M,},{,N}),匹配模式分为贪婪和非贪婪两种,默认是贪婪的
-
贪婪:在匹配成功的时候,有多种匹配结果,贪婪取最多次数对应的匹配结果。非贪婪取最少次数对应的匹配结果(匹配次数不确定的地方,有多种匹配方式都可以匹配成功,贪婪取最多次数,非贪婪取最少次数)
-
贪婪模式:,+,?,{M,N},{M,},{,N}
# 贪婪模式 result = match(r'a.+b', 'amb计算bxxbmn') print(result) # <re.Match object; span=(0, 9), match='amb计算bxxb'>
-
非贪婪模式:?,+?,??,{M,N}?,{M,}?,{,N}?
result = match(r'a.+?b', 'amb计算bxxbmn') print(result) # <re.Match object; span=(0, 3), match='amb'>
-
注意:如果匹配结果只有一种可能,那么贪婪和非贪婪的结果一样
# 注意:如果匹配结果只有一种可能,那么贪婪和非贪婪的结果一样 result = match(r'a.+b', 'ambxx') print(result) # <re.Match object; span=(0, 3), match='amb'> result = match(r'a.+?b', 'ambxx') print(result) # <re.Match object; span=(0, 3), match='amb'>
5. 分组和分支
-
分组 - ()
-
整体 - 将正则表达式中的一部分看作一个整体进行相关操作
# 1)将正则表达式中的一部分看作一个整体进行相关操作 result = fullmatch(r'(\d\d[A-Z]{2})+','12HG23ER45JI56KO') print(result)# <re.Match object; span=(0, 16), match='12HG23ER45JI56KO'>
-
重复 - 可以在正则表达式中通过\M来重复他前面的第M个分组的匹配结果
-
注意:\M 只能重复在他之前出现的分组内容,无法重复在他之后出现的分组内容
# 重复 result = fullmatch(r'(\d{2})[a-z]\1','78k78') print(result)# <re.Match object; span=(0, 5), match='78k78'> result = fullmatch(r'(\d{2})([a-z]{2})=\2{2}\1{2}','12ik=ikik1212') print(result)#<re.Match object; span=(0, 13), match='12ik=ikik1212'>
-
-
捕获findall - 分为手动捕获和自动捕获两种(只获取正则表达式中的分组匹配到的结果)
# 提取金额对应的数字 message = "每天3000元,其中10元吃早餐,30元吃午餐,50元晚餐,200元夜宵,熬到凌晨2点,体重每天增加10斤,寿命每天减少30分钟" result = findall(r'(\d+)元',message) print(result)# ['3000', '10', '30', '50', '200']
-
-
分支
-
正则1|正则2|正则3|… - 匹配可以和多个正则中任意一个正则匹配的字符串
-
注意:如果想要正则表达式中的一部分实现多选一的效果,那变化的部分用分组表示
# 分支 # a123b或者afegb result = fullmatch(r'a(\d{3}|[a-z]{3})b','a125b') print(result)
-
6. 转义符号
-
转义符号:
-
正则中的转义符号,就是在本身具有特殊功能或者特殊意义的符号前加"",让这个符号变成一个普通符号
# 正则中的转义符号, result = fullmatch(r'\d+\+\d+',"456+123") print(result) #<re.Match object; span=(0, 7), match='456+123'> result = fullmatch(r'\d+\.\d+','12.7') print(result) #<re.Match object; span=(0, 4), match='12.7'> result = fullmatch(r'\([a-z]+\)',"(asdf)") print(result) # <re.Match object; span=(0, 6), match='(asdf)'>
-
单独存在有特殊意义的符号(+,*,?,.),在[]中特殊意义会自动消失
# 单独存在有特殊意义的符号(+,*,?,.),在[]中特殊意义会自动消失 result = fullmatch(r'a[*%+-^]b','a*b') print(result) #<re.Match object; span=(0, 3), match='a*b'>
-
本身在[]中有特殊功能的符号,如果要表示普通符号,必须加""
result = fullmatch(r'a[a\-z]b','a-b') print(result) #<re.Match object; span=(0, 3), match='a-b'> result = fullmatch(r'1[\^a\-z]2','1^2') print(result) #<re.Match object; span=(0, 3), match='1^2'>
-
7. 检测类目符号
-
检测类符号是在匹配成功的情况下,检测检测类符号所在的位置是否是符号相关要求
-
\b - 检测是否是单词边界
-
单词边界:可以将两个单词区分开的符号都是单词边界,比如:空白符号,英文标点符号,字符串开头和字符串结尾
message = '203mn45,89 司机34kn;23;99mll==910,230 90=' result = findall(r'\b\d+', message) print(result) # ['203', '89', '23', '99', '910', '230','90'] result = findall(r'\b\d+\b', message) print(result) # ['89', '23', '910', '230', '90']
-
-
\B - 检测是否不是单词边界
message = '203mn45,89 司机34kn;23;99mll==910,230 90=' result = findall(r'\B\d+\B', message) print(result)#['03', '4', '34', '9', '1', '3']
-
^ - 检测是否是字符串开头
# 提取字符串前5个字符 message = '203mn45,89 司机34kn;23;99mll==910,230 90=' result = findall(r'^.{5}', message) print(result) # ['203mn']
-
$ - 检测是否是字符串结尾
# 提取字符串最后5个字符 message = '203mn45,89 司机34kn;23;99mll==910,230 90=' result = findall(r'.{5}$', message) print(result)
-
8. re模块常用函数
-
Python的re模块:re模块是Python用来支持正则表达式的模块,模块中包含了所有的和正则相关的的函数。
-
常用函数:
-
fullmatch(正则表达式,字符串) - 完全匹配,判断整个字符串是否符合正则表达式描述的规则,匹配成功返回匹配对象,匹配失败返回空
# fullmatch(正则表达式, 字符串) - 完全匹配,判断整个字符串是否符合正则表达式描述的规则,匹配成功返回匹配对象,匹配失败返回空 result = fullmatch(r'\d{3}', '234') print(result)#<re.Match object; span=(0, 3), match='234'>
-
match(正则表达式,字符串) - 匹配字符串开头,判断字符串开头是否符合正则表达式描述的规则,匹配成功返回匹配对象,匹配失败返回空
result = match(r'\d{3}', '823介绍数据库') print(result)# <re.Match object; span=(0, 3), match='823'>
-
findall(正则表达式,字符串) - 获取字符串所有的满足正则的字串,返回一个列表,列表中的元素是字符串
-
注意:如果正则表达式中有分组,会针对分组做自动捕获(只获取分组匹配到的结果)
result = findall(r'\d{3}', 'ba203还是678说kk0222jksn就是23311') print(result) #['203', '678', '022', '233']
-
-
search(正则表达式,字符串) - 获取字符串第一个能够和正则匹配的子串,能够找到返回匹配对象,匹配失败返回空
result = search(r'\d{3}', 'ba203还是678说') print(result) # <re.Match object; span=(2, 5), match='203'>
-
finditer(正则表达式,字符串) - 获取字符串中所有的满足正则的字串,返回一个迭代器,
result = finditer(r'\d{3}', 'ba203还是678说kk0222jksn就是23311') print(result) print(list(result))
-
split(正则表达式,字符串) - 将字符串中所有的满足正则的字串作为切割点对字符串进行切割
str1 = '123aMKnb嗑生嗑死aKKssa923b===' # 将str1中的a和b作为切割点对字符串进行切割 result = split(r'a|b', str1) print(result) # ['123', 'MKn', '嗑生嗑死', 'KKss', '923', '===']
-
sub(正则表达式,字符串1,字符串2) - 将字符串2中所有满足正则的字串都替换成字符串1
result = sub(r'\d+', '+', 'ba203还是678说kk0222jksn就是23311') print(result)
-
-
匹配对象
-
直接获取整个正则表达式对应的匹配结果: 匹配对象.group()
result = search(r'(\d{3})([A-Z]{2})', '-=2设计师234KM222哈哈宿舍239KH') print(result.group()) # '234KM'
-
手动捕获某个分组对应的匹配结果: 匹配对象.group(分组数)
print(result.group(1)) # '234' print(result.group(2)) # 'KM'
-
获取匹配结果在原字符串中的位置: 匹配对象.span()
print(result.span()) # (6, 11) print(result.span(2)) # (9, 11)
-
-
参数
-
匹配忽略大小写:(?i)
result = fullmatch(r'(?i)abc', 'ABC') print(result)# <re.Match object; span=(0, 3), match='ABC'>
-