一、认识正则表达式
什么是正则表达式
-
正则表达式是一种可以让复杂的字符串变得简单的工具。
-
不管使用正则解决的是什么样的字符串问题,写正则表达式的目的只有一个:用正则表达式描述字符串规则
二、正则表达式匹配类型
1. 正则表达式
写正则表达式就是用各种各样的正则符号来描述字符串规则
2. re模块
-
re模块是python的系统模块,这个模块中提供了各种各样和正则表达式相关的函数。 在python中使用正则表达式是通过re模块中的函数来用的。
-
fullmatch(正则表达式, 字符串):
完全匹配,让整个字符串和正则进行匹配(判断整个字符串是否符合正则表达式所描述的规则),如果匹配成功返回值是匹配对象,匹配失败返回None
-
注:正则表达式的格式 - r'正则表达式'
3.匹配类符号
-
普通符号 - 表达式符号本身**
from re import fullmatch result = fullmatch(r'abc', 'abc') print(result)
-
. - 匹配任意一个字符
result = fullmatch(r'.bc', '块bc') print(result)
-
\d - 匹配任意一个数字字符
result = fullmatch(r'a\db', 'a3b') print(result)
-
\s - 匹配任意一个空白字符(空格、\t、\n)
result = fullmatch(r'a\sb', 'a b') print(result)
-
\w - 匹配任意一个字母、数字、下划线和中文
result = fullmatch(r'a\wb', 'a块b') print(result)
-
\D、\S、\W
\D - 匹配任意一个非数字字符 \S - 匹配任意一个非空白字符 \W - 匹配任意一个非(数字、字母、下划线或者中文) result = fullmatch(r'1\D2\S3\W', '1,2集3#') print(result)
-
[字符集] - 匹配在字符集中的任意一个字符
[MNA] - 匹配M或者N或者A [\dMN] - 匹配任意一个数字或者M或者N [1-9] - 匹配数字字符1到9中的任意一个 [a-z] - 匹配任意一个小写字母 [a-zA-Z] - 匹配任意一个字母 [a-zA-Z\d] - 匹配任意一个字母或者数字 [a-zA-Z\d+] - 匹配任意一个字母或者数字或者+
# 'aAb' result = fullmatch(r'a[MNA]b', 'aMb') print(result) # '+34'、'-45'、'-98' result = fullmatch(r'[+-]\d\d', '+90') print(result) result = fullmatch(r'a[MN\d]b', 'aMb') print(result) result = fullmatch(r'a[1-8]b', 'a2b') print(result) result = fullmatch(r'a[\u4e00-\u9fa5]b', 'a是b') print(result)
-
[^字符集] - 匹配不在字符集中的任意一个字符
result = fullmatch(r'a[^MN]b', 'a@b') print(result) result = fullmatch(r'a[^A-Z]b', 'amb') print(result)
-
注意:- 只有放在两个字符之间的时候才表示谁到谁,并且它前面的字符的编码值必须小于-后面的字符的编码值。
三、匹配次数
1. * - 任意次数(包括0次)
from re import fullmatch, match, findall result = fullmatch(r'a\d*b', 'a890b') print(result) result = fullmatch(r'a*\db', 'aaaa3b') print(result) result = fullmatch(r'a[A-Z]*b', 'aMMKb') print(result)
2. + - 至少1次
result = fullmatch(r'a\d+b', 'a23b') print(result)
3. ? - 最多1次(0次或者1次)
# '-7283' result = fullmatch(r'-?\d+', '-2344') print(result)
4. {}
{N} - N次 {M,N} - M到N次 {M,} - 至少M次 {,N} - 最多N次 result = fullmatch(r'\d{3,5}abc', '2492abc') print(result)
5.贪婪和非贪婪
-
在匹配次数不确定的时候,匹配模式可以分为贪婪和非贪婪两种。
-
在能匹配成功的情况下,如果有多种次数都可以匹配成功,贪婪取最多的那个次数进行匹配,非贪婪取最少的那个次数进行匹配。
-
贪婪模式:*、+、?、{M,N}、{M,}、{,N}
-
非贪婪模式:*?、+?、??、{M,N}?、{M,}?、{,N}?
-
补:match(正则, 字符串) - 匹配字符串开头
# 2 5 8 result = match(r'a.+b', 'amnb你好b12b开始三大') print(result) # <re.Match object; span=(0, 10), match='amnb你好b12b'> result = match(r'a.+?b', 'amnb你好b12b开始三大') print(result) # <re.Match object; span=(0, 4), match='amnb'>
四、分支和分组
1. 分支 - |
-
正则表达式1|正则表达式2 : 先让字符串和正则表达式1进行匹配,如果失败再和正则表达式2进行匹配
from re import * # 'abcMKJ'、'abc23'、'abcMHA'、 'abc34' result = fullmatch(r'abc[A-Z]{3}|abc\d{2}', 'abc23') print(result) result = fullmatch(r'abc([A-Z]{3}|\d{2})', 'abc23') print(result)
2. 分组 - ()
-
整体操作
# 'M12K34L45...' result = fullmatch(r'([A-Z]\d{2})+', 'K34P23H34B23') print(result) result = fullmatch(r'abc([A-Z]{3}|\d{2})', 'abc23') print(result)
-
重复
在正则表达式中可以通过 '\N' 来重复它前面第N个分组匹配到的结果 (N指的是任意一个正整数)
# 'mn123mn'、'kh234kh'、'ak109ak' result = fullmatch(r'([a-z]{2})\d{3}\1', 'mn123mn') print(result) result = fullmatch(r'([A-Z]{3})abc(\d{2})\1\2{3}', 'MKJabc12MKJ121212') print(result)
-
捕获
-
自动捕获:findall这个函数中的正则表达式中如果有分组,获取匹配结果是时候自动捕获分组匹配到的结果
findall(正则表达式, 字符串) - 提取字符串中所有满足正则表达式的子串
result = findall(r'(\d{3})[\u4e00-\u9fa5]', 'm234mn数据290mk283-js2839吗=239科技师范=2800=') print(result)
-
手动捕获 - 如果正则函数的结果是匹配对象,在正则表达式中有分组的时候,就可以对匹配对象进行手动捕获(手动获取分组匹配到的结果)
result = match(r'(\d{3})([\u4e00-\u9fa5])', '234吗lkshkf 沙发沙发') print(result) # <re.Match object; span=(0, 4), match='234吗'> # 匹配对象.group() - 获取整个正则表达式匹配到的结果 # 匹配对象.group(N) - 获取匹配结果中第N个分组匹配到的内容 print(result.group()) # 234吗 print(result.group(1)) # 234 print(result.group(2)) # 吗
-
五、检测类符号(了解)
-
注意:检测类符号不参与匹配,只是在匹配成功之后检测检测类符号所在的位置是否符合相关的要求。
1. \b :
检测是否是单词边界(可以将两个单词区分开的符号都属于单词边界) """ 常见的单词:空格、\t、\n、英文的标点符号、字符串开头、字符串结尾
result = fullmatch(r'[a-z]{2}\s\b[a-z]{2}', 'mn kj') print(result) result = findall(r'\b\d{3}\b', '123开始234,啥时间235kks,233.393jsd290 大姐夫237 892') print(result)
2. \B - 检测是否不是单词边界
result = findall(r'\B\d{3}\B', '123开始234,啥时间235kks,233.393jsd290 大姐夫237 892') print(result)
3. ([]外面的) - 检测是否是字符串开头
4. $ - 检测是否是字符串结尾
六、转义字符
1. 转义符号
在本身具有特殊功能或者特殊意义的符号前加\,让符号的功能消失变成一个普通符号
# 23.78、34.90、23.00 result = fullmatch(r'\d{2}\.\d{2}', '23.89') print(result) # +233、+929 result = fullmatch(r'\+\d{3}', '+234') print(result)
2. 独自存在有特殊功能的符号在[]中对应的功能会消失,变成一个普通符号
在[]里面有特殊功能的符号,也可以通过加\让其功能消失
result = fullmatch(r'\d{2}[.]\d{2}', '23.89') print(result) result = fullmatch(r'\d{2}[a\-z\]]\d{2}', '23]89') print(result)
七、re模块
from re import fullmatch, match, search, findall, finditer, split, sub
1. fullmatch(正则表达式, 字符串)
完全匹配,如果匹配成功结果是匹配对象,匹配失败结果是None
print(fullmatch(r'\d{3}', '234'))
2. match(正则表达式, 字符串)
匹配字符串中第一个满足正则的子串,如果匹配成功结果是匹配对象,匹配失败结果是None
print(search(r'\d{3}', '世纪东方234健康983jsk'))
3. search(正则表达式, 字符串)
匹配字符串中第一个满足正则的子串,如果匹配成功结果是匹配对象,匹配失败结果是None
print(search(r'\d{3}', '世纪东方234健康983jsk'))
4. findall(正则表达式, 字符串)
提取字符串中所有满足正则的子串,如果正则表达式中有分组,只获取分组匹配到的结果。返回值是一个列表,列表中的元素是匹配到的结果
print(findall(r'\d{3}', '234hsj892,时间段反馈2893,是233 sfh2839数据923和829-=sjdf23k'))
# ['839', '923'] print(findall(r'(\d{3})[\u4e00-\u9fa5]', '234hsj892,时间段反馈2893,是233 sfh2839数据923和829-=sjdf23k')) # 如果正则中有多个分组,列表中的元素是元组 # [('839', '数'), ('923', '和')] print(findall(r'(\d{3})([\u4e00-\u9fa5])', '234hsj892,时间段反馈2893,是233 sfh2839数据923和829-=sjdf23k')) # 如果要获取整个正则的匹配结果,在整个正则表达式外面加分组 # a2a m3m z9z result = findall(r'(([a-z])\d\2)', '是符合m3m啥积分z9zSDK23b8b是否') print([x[0] for x in result])
5. finditer(正则表达式, 字符串)
匹配字符串中所有满足正则的子串,返回值是一个迭代器,迭代器中的元素是匹配对象
result = finditer(r'\d{3}', '234hsj892,时间段反馈2893,是233 sfh2839数据923和829-=sjdf23k') for x in result: print(x.group())
6. split(正则表达式, 字符串)
将字符串中所有满足正则的子串作为切割点对字符串进行切割
result = split(r'\d{3}', '234hsj892,时间段反馈289323,是233 sfh2839数据923和829-=sjdf23k') print(result) result = split(r'\d{3}', '234hsj892,时间段反馈289323,是233 sfh2839数据923和829-=sjdf23k', 2) print(result)
7. sub(正则表达式, 字符串1, 字符串2)
将字符串2中所有满足正则的子串都替换成字符串1
result = sub(r'\d{3}', 'xx', '234hsj892,时间段反馈289323,是233 sfh2839数据923和829-=sjdf23k') print(result)
8. 正则参数
-
单行匹配和多行匹配
. 在 单行匹配的时候可以和任何字符进行匹配,多行匹配的.无法和换行符(\n)进行匹配。(默认是多行匹配)
-
单行匹配的匹配方法:
-
在正则表达式的最前面加 '(?s)'
-
给函数flags参数赋值为re模块中的 'S'
# 默认是多行匹配 result = fullmatch(r'a.b', 'a\nb') print(result) # 单行匹配 result = fullmatch(r'(?s)a.b', 'a\nb') print(result) # 单行匹配 from re import S result = fullmatch(r'a.b', 'a\nb', flags=S) print(result)
-
-
-
忽略大小
让小写字母可以和对应的大写字母进行匹配;大写字母也可以和对应的小写字母进行匹配
-
在正则表达式的最前面加 '(?i)'
-
给参数flags赋值为re模块中 'I'
# 默认不会忽略大小写 result = fullmatch(r'a\db', 'A4b') print(result) # 忽略大小写 result = fullmatch(r'(?i)a\db', 'A4b') print(result) # 忽略大小写 from re import I result = fullmatch(r'a\db', 'A4b', flags=I) print(result) # 忽略大小写的同时做单行匹配 result = fullmatch(r'(?is)a.b', 'A\nb') print(result) result = fullmatch(r'a.b', 'A\nb', flags=S|I) print(result)
-