一、认识正则表达式
1.正则表达式的作用
正则表达式是一种可以让复杂的字符串问题变得简单的工具
# 问题:判断手机号是否合法
# 方法1:
# tel = '13186125181'
# if len(tel) != 11:
# print('不是合法的手机号')
# else:
# for x in tel:
# if not '0' <=x <'9':
# print('不是合法的手机号')
# break
# else:
# if tel[0] != '1':
# print('不合法')
# elif '3' <=tel[1] <'9':
# print('合法')
# else:
# print('不合法')
# 方法2:
# tel = '13186125181'
# from re import fullmatch
# print(fullmatch(r'1[3-9]\d{9}', tel) != None)
# from re import split
# str2 = '23+45-89-1928*233'
# print(split(r'[+*-]',str2))
2.fullmatch函数
full match(正则表达式,字符串) - 判断字符串和正则表达式是否完全匹配(判断整个字符串是否符合正则表达式所描述的规则),如果不符合则返回None
python提供正则表达式的方式:直接将正则表示作为一个字符串内容(正则需要使用引号引起来,而且引号前面一般需要加r)
二、 正则表达式的语法
from re import fullmatch
# 写正则表达式都是通过正则符号描述字符串规则
# 1.匹配类符号 - 用来规定字符(用来描述对字符的要求)
# 1).普通字符 - 除了特殊字符以外的符号都是普通字符(在正则中表示符号本身)
print(fullmatch(r'abc', 'abc'))
# 2).'.' - 匹配任意一个字符
print(fullmatch(r'a.{3}c', 'afxdc'))
# 3).\d - 匹配任意一个数字字符
print(fullmatch(r'a\dc', 'a1c'))
# 4).\s - 匹配任意一个空白字符
# 空白字符:' ','\n','\t'
print(fullmatch(r'\d\d\s\d', '24 \t9'))
# 5).\w - 匹配任意一个数字 字母 下划线或者中文
print(fullmatch(r'a\wa', 'a_a'))
# 6).\D \S \W - 和对应的小写都是相反的
# \D - 匹配任意一个非数字字符
print(fullmatch(r'a\Ds', 'als'))
# \S - 匹配任意一个非空白字符
print(fullmatch(r'\S{6}', '幸运色是紫色'))
# \W - 匹配任意一个非数字 字母 下划线或者中文字符
print(fullmatch(r'z\Ws', 'z s'))
# 7).[字符集] - 匹配字符集中任意一个字符
"""
用法1:在[]中提供多个普通字符,匹配多个字符中的任意一个
用法2:[字符1-字符2],匹配字符1到2范围内中的任意一个
[5-9]:能匹配'5','6','7','8','9'
[a-z]:匹配任意一个小写字母
[\u4e00-\u9fa5]:匹配任意一个中文
[a-Az-Z]:匹配任意一个字母
[mn1-9]
用法3:在[]中包含\开头的特殊符号
[\da-z]:匹配任意一个数字或者任意一个小写字母
[\da-zA-Z_\u4e00-\u9fa5] == \w
注意:[]中的减号只有在两个字符中间的时候才表示谁到谁
"""
print(fullmatch(r'a[zls]s', 'als'))
# 8)[^字符集] - 匹配不在字符集中任意一个字符
"""
[^A-Z]:匹配任意一个非大写字母
[^mn]:匹配任意一个非mn的字符
"""
2.匹配次数
任何匹配类符号后面都可以添加次数对应的符号来控制字符的个数
# 1) + -匹配一次或者多次
print(fullmatch(r'a+', 'aaa'))
print(fullmatch(r'\d+a', '24a'))
print(fullmatch(r'a.+b', 'afasafab'))
print(fullmatch(r'a[1-5]+b', 'a2245b'))
# 2)* - 匹配零次或者多个(任意次数)
print(fullmatch(r'a*l', 'aaaaaaaaaal'))
# 3)? - 匹配0次或者1次
print(fullmatch(r'a?l', 'aal'))
# 4){}
# {N} - N 次
# {M,N} - M到N次
# {M,} - 至少M次
# {,N} - 最多N次
# 5)贪婪和非贪婪 -
"""
如果匹配次数不确定,匹配的时候分为贪婪和非贪婪两种模式(默认是贪婪模式)
贪婪模式:在多种匹配次数都可以匹配成功的时候,贪婪取最多的次数进行匹配
非贪婪模式:在多种匹配次数都可以匹配成功的时候,非贪婪取最少的次数进行匹配
(在不确定的匹配次数后面再加一个?:+? *? ?? {M,N}? {M,}? {,N}?)
"""
from re import match,findall
# match(正则表达式,字符串) - 匹配字符串开头
print(fullmatch('\d{3}', '132'))
print(match(r'924\d{3}', '728爱好的撒'))
print(match(r'a.+b', 'amnb还是b的话')) # <re.Match object; span=(0, 7), match='amnb还是b'>
print(match(r'a.+?b', 'amnb还是b的话')) # <re.Match object; span=(0, 7), match='amnb'>
print(match(r'a.+b', 'amnb还是b的话'))
print(match(r'a.+?b', 'amnb还是b的话'))
massage = '<afa924->睡觉sdsa<546萨芬>afa<0-2=2-256飞洒发>fgd'
result = findall(r'<.+?>',massage)
print(result)
3.分组和分支
1)分组 - ()
“”"
分组就是用()将正则的部分内容括起来表示一个整体
a.整体控制(将正则中一部分内容括起来整体控制次数)
b.重复(在正则中用\M来重复它前面 第M个分组匹配到的结果)
c.捕获(在获取匹配结果的时候可以自动(findall)或者手动的获取某个分组匹配的结果)
“”"
# 1)整体控制
print(fullmatch(r'(\d\d[a-z]{3})+','24lsa89asd'))
# 2)重复
print(fullmatch(r'(\d\d)[a-z]{3}\1','24lsa24'))
# 3)自动捕获
massage = '<afa924->睡觉sdsa<546萨芬>afa<0-2=2-256飞洒发>fgd'
result = findall(r'<.+?>',massage)
print(result)
2).分支 - |
正则1|正则2|正则3|…
正则1|正则2|
print(fullmatch(r'\d{3}|[a-z]{3}','aas'))
print(fullmatch(r'abc(\d{3}|[a-z]{3})','abc123'))
from re import fullmatch,match,findall,split,search,sub,finditer
# fullmatch(正则,字符串) - 完全匹配
# match(正则,字符串) - 匹配字符串开头
# findall(正则,字符串) - 提取字符串中所有满足正则的子串,返回一个列表
# split(正则,字符串) - 将字符串中所有满足正则的子串作为切割点对字符串进行切割
# search(正则, 字符串) - 匹配字符串中第一个满足正则的字符串
# sub(正则, 字符串1, 字符串2) - 将字符串2中所有满足正则的子串都替换成字符串1
# finditer(正则, 字符串) - 提取字符串中所有满足正则的子串; 返回一个迭代器,迭代器中的元素是匹配对象
4.检测类符号
先匹配,匹配成功后再来看看检测类符号所在的位置是否符合相关要求
\b - 检测是否是单词边界(单词边界指的是任何两个可以将两个单词区分开来的符号:空白符号 英文标点符号 字符串开头和字符串结尾)
^ - 检测是否是字符串开头
$ - 检测是否是字符串结尾
print(fullmatch(r'abc\b123','abcmn'))
5.转移符号
- 在具有特殊意义的符号前加’'让这个有特殊意义的符号变成一个普通的符号
# 案例:匹配任意一个小数
print(fullmatch(r'\d+\.\d+','23.34'))
# 补充:除了\开头的特殊符号,其他符号放在[]中对应的特俗功能会自动消失