day 16 python第一阶段基础语法学习 ——正则表达式
一、认识正则表达式
1.正则表达式的作用
正则表达式是一种可以让复杂的字符串问题变得简单的工具
引入问题:判断手机号是否合法
方法1:不是用正则时
tel = '182839202303'
if len(tel) != 11:print('不是合法的手机号')
else:for x in tel:if not '0' <= x <= '9':print('不是合法的手机号')breakelse:if tel[0] != '1':print('不是合法的手机号')elif '3' <= tel[1] <= '9':print('是合法的手机号')else:print('不合法')
方法2:
tel = '13283920303'
from re import fullmatch
print(fullmatch(r'1[3-9]\d{9}', tel) != None)
获取 2345891928233
from re import split
str2 = '23+45-89-1928*233'
print(split(r'[+*-]', str2))
fullmatch
**fullmatch(正则表达式, 字符串)
python提供正则表达式的方式:直接将正则表示作为一个字符串内容(正则需要使用引号引起来,而且引号前面一般需要加r)
二、正则表达式
from re import fullmatch
写正则表达式都是通过正则符号来描述字符串规则
1)普通字符 - 除了特殊符号以外的符号都是普通字符(在正则中表示符号本身)
print(fullmatch(r'abc', 'abc'))
#<re.Match object; span=(0, 3), match='abc'>
2) (. ) - 匹配任意一个字符
print(fullmatch(r'a.c', 'a+c'))
print(fullmatch(r'a..c', 'a+和c'))
#<re.Match object; span=(0, 3), match='a+c'>
#<re.Match object; span=(0, 4), match='a+和c'>
3)\d - 匹配任意一个数字字符
print(fullmatch(r'a\dc', 'a1c'))
print(fullmatch(r'\d\d\d', '728'))
#<re.Match object; span=(0, 3), match='a1c'>
#<re.Match object; span=(0, 3), match='728'>
空白字符:’ ‘(空格)、’\n’、‘\t’
print(fullmatch(r'\d\d\s\d', '23\t5'))
# <re.Match object; span=(0, 4), match='23\t5'>
print(fullmatch(r'a\wa', 'a_a'))#
\D - 匹配任意一个非数字字符
print(fullmatch(r'a\Dc', 'a框c'))
#<re.Match object; span=(0, 3), match='a框c'>
\S - 匹配任意一个非空白字符
空白字符:’ ‘(空格)、’\n’、‘\t’
print(fullmatch(r'\d\d\S\d','24啊5'))
# <re.Match object; span=(0, 4), match='24啊5'>
\W - 匹配任一个非数字、非字母、非下划线或者中文
print(fullmatch(r'a\Wd','a?d'))
# <re.Match object; span=(0, 3), match='a?d'>
7)[字符集] - 匹配字符集中任意一个字符
用法1: 在[]中提供多个普通字符, 匹配多个字符中的任意一个
用法2:[字符1-字符2],匹配字符1到字符2范围中的任意一个字符
用法3:在[]中包含\开头的特殊符号
[\da-zA-Z_\u4e00-\u9fa5] == \w
print(fullmatch(r'a[mn1]b', 'a1b
print(fullmatch(r'abc[\u4e00-\u9fa5]', 'abc就'))
print(fullmatch(r'[-az]abc', '-abc'))
#<re.Match object; span=(0, 3), match='a1b'>
#<re.Match object; span=(0, 4), match='abc就'>
#<re.Match object; span=(0, 4), match='-abc'>
^字符集]
[^mn]: 匹配除了m和n以外的任何一个字母
2. 匹配次数
任何匹配类符号后面都可以添加匹配次数对应的符号来控制字符的个数
1) + - 匹配1次或者多次(至少1次)
print(fullmatch(r'a+', 'aaaaaa'))
print(fullmatch(r'\d+a', '8292333a'))
print(fullmatch(r'a.+b', 'amksk数据s--=2b'))
print(fullmatch(r'a[1-5]+b', 'a43b'))
#<re.Match object; span=(0, 4), match='-abc'>
#<re.Match object; span=(0, 6), match='aaaaaa'>
#<re.Match object; span=(0, 8), match='8292333a'>
#<re.Match object; span=(0, 13), match='amksk数据s--=2b'>
#<re.Match object; span=(0, 4), match='a43b'>
2) * - 匹配0次或者多个(任意次数)
print(fullmatch(r'a\d*b', 'a2233b'))
# <re.Match object; span=(0, 6), match='a2233b'>
print(fullmatch(r'a\d*b', 'ab'))
# <re.Match object; span=(0, 6), match='ab'>
3) ? - 匹配0次或者1次
print(fullmatch(r'-?abc', '-abc'))
#<re.Match object; span=(0, 4), match='-abc'>
4) {}
{N} - N次
{M,N} - M到N次
{M,} - 至少M次
{,N} - 最多N次
print(fullmatch(r'a\d{3}b', 'a783b'))
print(fullmatch(r'a\d{3,5}b', 'a345b'))
print(fullmatch(r'a\d{3,}b', 'a89233423b'))
print(fullmatch(r'a\d{,3}b', 'a232b'))
# <re.Match object; span=(0, 5), match='a783b'>
<re.Match object; span=(0, 5), match='a345b'>
<re.Match object; span=(0, 10), match='a89233423b'>
<re.Match object; span=(0, 5), match='a232b'>
5)贪婪和非贪婪
如果匹配次数不确定,匹配的时候分为贪婪和非贪婪两种模式(默认是贪婪模式)
a.贪婪模式: 在多种匹配次数都可以匹配成功的时候,贪婪取最多的次数来进行匹配
b.非贪婪模式: 在多种匹配次数都可以匹配成功的时候,非贪婪取最少的次数来进行匹配
(在不确定的匹配次数后面再加一个?: +?、*?、??、{M,N}?、{M,}?、{,N}?
**from re import match, findall**
``match(正则表达式, 字符串)` - 匹配字符串开头
print(fullmatch('\d{3}', '233'))
print(match(r'\d{3}', '728空间数据水电费'))
#<re.Match object; span=(0, 3), match='233'>
<re.Match object; span=(0, 3), match='728'>
# 2 -> amnb
# 4 -> amnb还b
print(match(r'a.+b', 'amnb还b上课')) # <re.Match object; span=(0, 6), match='amnb还b'>
print(match(r'a.+?b', 'amnb还b上课')) # <re.Match object; span=(0, 4), match='amnb'>
print(match(r'a.+b', 'amnb还上课'))
print(match(r'a.+?b', 'amnb还上课'))
#<re.Match object; span=(0, 4), match='amnb'>
<re.Match object; span=(0, 4), match='amnb'>
message = '<jhsj28->数sssjs<992函数>kss<0-2=2-2033是>宿舍'
result = findall(r'<.+?>', message)
print(result)
#['<jhsj28->', '<992函数>', '<0-2=2-2033是>']
3. 分组和分支
1)分组 - ()
分组就是用()将正则的部分内容括起来表示一个整体。
a. 整体控制(将正则中一部分内容括起来整体控制次数)
b. 重复(在正则中用\M来重复它前面第M个分组匹配到的结果)
c. 捕获(在获取匹配结果的时候可以自动(只有findall具有自动捕获的功能)或者手动的获取某个分组匹配的结果)
1)整体控制的案例
print(fullmatch(r'(\d\d[a-z]{3}){3}', '67kmn89ksm78kom'))
print(fullmatch(r'(\d\d[a-z]{3})+', '67kmn89jkm'))
#<re.Match object; span=(0, 15), match='67kmn89ksm78kom'>
#<re.Match object; span=(0, 10), match='67kmn89jkm'>
2)重复的案例
'23mnk23'、'89kms89' - 匹配成功
'23mnk45' - None
print(fullmatch(r'(\d\d)ab([A-Z]{3})-\2', '23abMKN-MKN'))
print(fullmatch(r'(\d\d)ab([A-Z]{3})-\2\1', '23abMKN-MKN23'))
print(fullmatch(r'(\d\d)ab([A-Z]{3})-\1{3}mn\2', '23abMKN-232323mnMKN'))
#<re.Match object; span=(0, 11), match='23abMKN-MKN'>
<re.Match object; span=(0, 13), match='23abMKN-MKN23'>
<re.Match object; span=(0, 19), match='23abMKN-232323mnMKN'>
3)自动捕获案例
message = '<jhsj28->数sssjs<992函数>kss<0-2=2-2033是>宿舍'
result = findall(r'<(.+?)>', message)
print(result)
#['jhsj28-', '992函数', '0-2=2-2033是']message = '哈吉斯234元看sjsj38000k0===233元开始看82993'
result = findall(r'(\d+)元', message)
print(result)
#['234', '233']
4. 检测类符号
先匹配,匹配成功后再来看检测类符号所在的位置是否符合相关要求
1)\b - 检测是否是单词边界(单词边界指的是任何可以将两个单词区分开来的符号:空白符号、英文标点符号、字符串开头和字符串结尾)
2)^ - 检测是否是字符串开头
3)$ - 检测是否是字符串结尾
message = '23sksm7823数据接口,232米好9022 28323,82923美女990'
print(findall(r'\b\d+\b', message))
#['28323]
#['23']message = '23sksm7823数据接口,232米好9022 28323,82923美女990'
print(findall(r'^\d+', message))
print(findall(r'\d+$', message))
#['23']
#['990']
5. 转义符号 - 在具有特殊意义的符号前加’'让这个有特殊意义的符号变成一个普通符号
案例:匹配任意一个小数
print(fullmatch(r'\d+\.\d+', '23.34'))
#<re.Match object; span=(0, 5), match='23.34'>
‘34+23’
print(fullmatch(r'\d\d\+\d\d', '34+23'))
#<re.Match object; span=(0, 5), match='34+23'>
'(234)'
print(fullmatch(r'\(\d{3}\)', '(345)'))
#<re.Match object; span=(0, 5), match='(345)'>
<!–补开头的特殊符号,其他符号放在[]中对应的特殊功能会自动消失–>
print(fullmatch(r'[.+\-?^\]]abc', ']abc'))
#<re.Match object; span=(0, 4), match=']abc'>
6.分支 - | (匹配其一相当于或)
正则1|正则2|正则3|…
正则1|正则2
'234'、'mns'
print(fullmatch(r'\d{3}|[a-z]{3}', 'amn'))
print(fullmatch(r'\d{3}|[a-z]{3}', '123'))
#<re.Match object; span=(0, 3), match='amn'>
<re.Match object; span=(0, 3), match='123'>
'abc234'、'abcMKJ'
print(fullmatch(r'abc\d{3}|abc[A-Z]{3}', 'abcMJK'))
print(fullmatch(r'abc(\d{3}|[A-Z]{3})', 'abcMKS'))
#<re.Match object; span=(0, 6), match='abcMJK'>
<re.Match object; span=(0, 6), match='abcMKS'>