一. 正则表达式
1. 匹配次数相关的正则符号
a. '+' 一次或多次(至少一次) ,控制+ 前面元素的次数,看下面事例
python
from re import fullmatch
'''
a+ 至少一个a ,
\d+ 至少一个数字字符
'''
result = fullmatch(r'1a+2','1aaaaaaaa2') #1和2中间至少要有一个a
print(result)
result = fullmatch(r'1\d+2','1454454545452') #1和2之间至少要有一个数字字符
print(result)
result = fullmatch(r'1[A-Z]+2','1DFER2')
print(result)
b. ' * ' 任意次数
python
result = fullmatch(r'1a*2','12') #和 + 唯一区别是, 可以一个元素都没有
print(result) # 1和2之间可以任意个a,可以没有a
c. ' ? ' --- 0次或者1次, 最多一次
python
result = fullmatch(r'1[\u4e00-\u9fa5]?2','1吗2') #1 和2之间0或1个中文字符
print(result)
d. { }
{ N } N次
{ M,N } M到N次
{M,}. 至少M次
{ ,N } 最次
python
result = fullmatch(r'1[3-9]\d{3}','13111') #\d任意数字字符只能三次
print(result)
result = fullmatch(r'1[3-9]\d{3,5}','1311111')#\d任意数字字符可以出现3次到5次(3,5也行)
print(result)
result = fullmatch(r'1[3-9]\d{3,}','13111') # 最少3次
print(result)
result = fullmatch(r'1[3-9]\d{,3}','1311') #最多三次,这里是两次
print(result)
2. 贪婪和非贪婪
1.定义:
- 如果在正则表达式中有不确定的匹配次数,这个正则在匹配字符串的时候可以分为贪婪和非贪婪两种模式
2. 贪婪(默认)
定义:如果一个字符串和正则进行匹配的时候有多种情况可以匹配成功,贪婪取最多的那个次数进行匹配
3.非贪婪( +?, *?, ??, {M,N}?, {M,}?, {,N}? )
定义:如果一个字符串恶和正则进行匹配时有多种情况可以匹配成功,非贪婪取最少的那个次数进行匹配
python
result = match(r'a[a-z]+?b','amnbdfdfbdfdfdfbd')
print(result)
#这样只会选择amnb, +? 是取最小的满足匹配规则的
3. match 和 fullmatch
match(正则表达式, 字符串) --- 匹配字符串开头
python
result = match(r'\d{3}','123的粉红色答复哈水电费哈水淀粉')
print(result)
#只匹配开头123,后面多少都可以
# 注意
result = match(r'a[a-z]+b','amnbdfdfbdfdfdfbd')
print(result)
#首先默认贪婪, 这里是a和b中间可以任意a-z字母, 但是后面这种有很多选择,amnb可以
#amnbdfdfb可以
4. 其他符号
1. 分组 ()
- a. 整体操作: 将正则表达式中的一部分内容用 () 括起来表示一个整体
python
result = fullmatch(r'(\d\d[a-z]{3}){3}','99qwe44ewq35oer')
print(result)
#( )括号括起来的一部分是一个整体,两个数据+三个字母 重复三次
result = fullmatch(r'(\d[A-Z])+abc','2W8Jabc')
print(result)
# 这里是 任意数字和任意大写字母的一个组合,可以重复多次, 最后加上 abc
- b. 重复 - 在正则表达式中可以用 \N 来重复 \N前面的第N个分组匹配到的内容
python
result = fullmatch(r'(\d{3})([A-Z]{2})=\2\1{3}','123AD=AD123123123')
print(result)
'''
先任意数字字符三个,选择123
然后任意一个大写字母,选择两个 AD
再来一个 =
再\2 第二个分组也就是 选个字母 执行两次 ,再来一个AD
再是\1{3} , 就是第一个分组, \d{3} 执行3次 ,也就是123 再写3次
'''
- c. 捕获 :获取匹配结果的时候只获取正则表达式中某个分组匹配到的内容
1.自动捕获:findall 函数支持自动捕获(findall在获取匹配结果的时候自动获取分组匹配到的结果)
findall(正则表达式, 字符串) --- 获取字符串所有符合正则表达式所描述的规则子串
python
result = findall(r'\d{3}','123AD=AD1231dfer231ddd23')
print(result) #找三个连续数字字符
#['123', '123', '231']
# 提取 前面要有中文字符的连续三个数字
result = findall(r'[\u4e00-\u9fa5](\d{3})','的123AD=AD大方123dfer的f231ddd23')
print(result) # 将三个连续字符这个要求用 () 分组 框起来,就只获取分组中内容
#['123', '123']
2.手动捕获: fullmatch 、match、search、finditer的结果都支持手动捕获
- match
python
result = match(r'([\u4e00-\u9fa5])(\d{3})','的123AD=AD大方123dfer的f231ddd23')
print(result.group(1),result.group(2),result.group())
# 的 123 的123
'''
result.group() 是输出你所要求的部分, 这里就是汉字+三个数字。汉字是第一个分组(括号括起来的)
result.group(1) 是你要求的部分且用分组符号括起来的, 就是汉字
result.group(2) 第二部分,就是 三个连续数字
'''
2. 分支 ' | '
- 语法: 正则1|正则2 理解为 or ,先让正则1和字符串匹配,如果失败再用正则2和字符串进行匹配(两个正则中只要有一个匹配成功就成功)
python
result = fullmatch(r'\d{3}abc|[A-Z]{3}abc','QWEabc')
print(result)
# 这是三个数字+abc 或 三个大写字母+abc都可
result = fullmatch(r'(\d{3}|[A-Z]{3})abc','123abc')
print(result)
# 用 分组() 框起来的部分,+abc , 分组中的 | 前后满足其一即可,最后是abc
3. 转义字符 在有特殊意义的符号前面加 \ , 让其功能消失变成一个普通符号。 注意:单独存在有特殊意义(除了\d \s \w等)的符号放在[ ]里面他的功能也会消失,变成普通符号 ( '-' 号只能放在最前或最后面,其他地方要加 \- , ^ 也是)
python
result = fullmatch(r'\d\d\.\d\d','23.55')
print(result)
# 想让一个小数进行匹配, 因为 . 在正则中是匹配任意字符功能,加个 \ ,让其功能消失
result = fullmatch(r'\d\d[.]\d\d','23.45')
print(result)
result = fullmatch(r'\(\d{3}\)','(183)')
print(result)
# 放在[] 里 符号失去功能
result = fullmatch(r'[.+?*(){}]abc','{abc')
print(result)
4. 检测类符号 (先匹配,如果匹配成功再检测,检测类所在的位置是否符合要求)
- ^ - 检测是否是字符串开头(只能放在正则的开头)
- $ - 检测是否字符串结尾(只能放在结尾)
- \b - 检测是否是单词边界(凡事可将两个英文单词区分开的符号都是单词边界:空白、英文标点符号、字符串开头和结尾)
- \B - 检测是否不是单词边界(board)
python
result = fullmatch(r'\d{3}\s\babc','342 abc')
print(result)
#\s 在这是空格, \b 检测a前面是否是单词边界
5. re模块
1. fullmatch 、 match、 search
- fullmatch(正则表达式,字符串) --- 完全匹配(让整个字符串进行匹配),如果匹配成功返回匹配对象,失败返回None
- match(正则表达式,字符串) --- 匹配字符串开头,如果匹配成功返回匹配对象,失败返回None
- search(正则表达式,字符串) --- 匹配字符串中第一个满足正则的子串,如果匹配成功返回匹配对象,失败返回None
2.findall 、finditer
- findall(正则表达式,字符串) --- 获取字符串中所有满足正则表达式的子串,结果是个列表,列表内容是字符串(正则中如果有分组会自动捕获)
python
result = findall(r'\d{3}','是的343非454非地方934非地方地方ffdf343方法')
print(result)
#['343', '454', '934', '343']
- finditer(正则表达式,字符串) --- 获取字符串中所有满足正则表达式的子串,结果是一个是迭代器,迭代器中元素是匹配对象
python
result = finditer(r'\d{3}','是的343非454非地方934非地方地方ffdf343方法')
print(list(result))
'''
[<re.Match object; span=(2, 5), match='343'>,
<re.Match object; span=(6, 9), match='454'>,
<re.Match object; span=(12, 15), match='934'>,
'''
3. splite(正则表达式,字符串)
将字符串所有满足正则的子串作为切割点对字符串进行切割
- splite(正则表达式,字符串,N) 将字符串前N个满足正则的子串作为切割点对字符串进行切割
python
result = split(r'\d{3}','是的343非454非地方934非地方地方ffdf343方法')
print(result)
result = split(r'\d{3}','是的343非454非地方934非地方地方ffdf343方法',3)
print(result)
4.sub
-
sub (正则表达式,字符串1,字符串2) 将字符串2中所有满足正则的子串都换成字符串1
-
sub (正则表达式,字符串1,字符串2,N) 将字符串2中前N 个满足正则的子串都替换成字符串1
python
result = sub(r'\d{3}','+','是的343非454非地方934非地方地方ffdf343方法')
print(result)
# 把连续三个数字换成 +
#是的+非+非地方+非地方地方ffdf+方法
result = sub(r'\d{3}','+','是的343非454非地方934非地方地方ffdf343方法',2)
print(result)
# 只换前两个
#是的+非+非地方934非地方地方ffdf343方法
5.正则参数
a. 1. 忽略大小写 匹配的时候让同一个字母的大写和小写相同
r'(?i)正则表达式'
python
result = fullmatch(r'(?i)[a-z]\d{3}','R345')
print(result)
a. 2. 加参数 I (ignorecase) from re import I 也是忽略大小写
给正则函数 flags = I
python
result = fullmatch(r'[a-z]\d{3}','R345',flags= I)
print(result)
b. 单行匹配 (默认是多行匹配)
- 多行匹配时正则中的 ' . '不能和 \n 匹配, 单行匹配的时候正则中的 ' . ' 是可以和 \n 进行匹配的 , 加一个(?s) s是single 单行匹配
python
result = fullmatch(r'(?s)a.b','a\nb')
print(result)
- 或者给正则函数flags 赋值为S(re模块中的S)
python
result = fullmatch(r'a.b','a\nb',flags=S)
print(result)
如何做到 又忽略大小写 又转为单行匹配
python
# 用(?si)
result = fullmatch(r'(?si)a.b','A\nb')
print(result)
# flags 参数赋值 S | I
result = fullmatch(r'a.b','A\nb',flags=S|I)
print(result)
# flags参数给s 成单行匹配, 在前面(?i)忽略大小写
result = fullmatch(r'(?i)a.b','A\nb',flags=S)
print(result)