正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎。
正则表达式的大致匹配过程是:依次拿出表达式和文本中的字符比较,如果每一个字符都能匹配,则匹配成功;一旦有匹配不成功的字符则匹配失败。如果表达式中有量词或边界,这个过程会稍微有一些不同,但也是很好理解的。
正则表达式并不是Python的一部分。
在python中,通过内嵌集成re模块,程序员们可以直接调用来实现正则匹配。
匹配 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
[] | 匹配中括号中的任意一个字符 |
[0-9] | 匹配任意一位数字 |
[a-z] | 匹配任意一位小写字母 |
[A-Z] | 匹配任意一位大写字母 |
[a-zA-Z0-9] | 匹配任意一位数字或字母 |
^[a-zA-Z] | 匹配以字母开头的字符串 |
[^a-z] | 匹配以除了小写字母开头的任意字符 |
\d | 匹配任意一个数字字符 [0-9] |
\D | 匹配任意除数字以外的任意字符 [^0-9] |
\w | 匹配数字字母下划线中的任意一个字符 [a-zA-Z0-9_] |
\W | 匹配除数字字母下划线以外的任意字符[^a-zA-Z0-9_] |
\s | 匹配空白符 |
\S | 匹配除空白字符以外的任意字符 |
概述:用来判断是否按照所规定的开始或结束
匹配 | 说明 |
---|---|
^ | 行首匹配 |
$ | 行尾匹配 |
\A | 行首匹配 多行匹配下有区别的 re.M |
\Z | 行尾匹配 多行匹配下有区别的 re.M |
限定正则匹配次数
匹配 | 说明 |
---|---|
(xyz) | 匹配括号内的xyz 作为整体匹配 子存储 |
? | 匹配一次或0次 |
* | 匹配任意次(或0次) |
+ | 匹配一次至多次 |
{n} | 确定匹配n次 |
{n,} | 至少匹配n次 |
{n, m} | 匹配n到m次 |
x|y | 匹配x或y |
示例
1. []
[abc] 匹配字母a/b/c
[AaBb] 匹配大小写ab
2. ^
a[a-zA-Z] 匹配首字母是a第二位任意字母 1ab
^a[a-zA-Z] 匹配首字母是a第二位任意字母 ab
3. $
[a-z]$ 匹配以字母结尾的字符
4. ^$组合
1[3-9][0-9]{9} 包含手机号码就可以 17346570232vasdsdsa
^1[3-9][0-9]{9}$ 精准匹配手机号码就可以 17346570232
5. {n}
[1-9][0-9][0-9]
[1-9][0-9]{2} 匹配三位数字
[a-zA-Z0-9_]{3}
6. {n, m}
[1-9][0-9]{4, 9} 匹配qq号
7. .* 匹配除换行符以外的任意字符任意次
"<b>.*</b>" <b>a</b><b>b</b> ("<b>a</b><b>b</b>")
8. .*? 匹配除换行符以外的任意字符任意次 拒绝贪婪匹配 <b>a</b>,<b>b</b>
"<b>.*?</b>" <b>a</b><b>b</b> ("<b>a</b>","<b>b</b>")
9. .+ 匹配除换行符以外的字符至少一次 贪婪
\d+
"<b>.+</b>" <b></b>
10. +? 拒绝贪婪匹配
11. ?
-?[1-9] 匹配一位正负整数
-{0,1}\d
-
作用
对正则进行修正
-
使用
search/match/findall/sub/subn/finditer 等函数 flags参数的使用
修饰符 | 描述 |
---|---|
re.I | 不区分大小写 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $的功能 |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
-
获取匹配结果
- group() 通过索引获取值 (索引可以不给)
- groups() 返回一个包含所有字符串的元组(子存储的值)
-
获取匹配后的索引位置
- span()
-
示例
re.I
print(re.findall('[a-z]','AaBb')) print(re.findall('[a-z]','AaBb', flags=re.I))
re.M
myStr = """asadasdd1\nbsadasdd2\ncsadasdd3""" print(re.findall('^[a-z]',myStr, )) print(re.findall('\A[a-z]',myStr)) print(re.findall('\d$',myStr)) print(re.findall('\d\Z',myStr)) # re.M print(re.findall('^[a-z]',myStr, flags=re.M)) print(re.findall('\A[a-z]',myStr, flags=re.M)) print(re.findall('\d$',myStr, flags=re.M)) print(re.findall('\d\Z',myStr, flags=re.M))
re.S
print(re.findall('<b>.*?</b>','<b>b标签</b>')) print(re.findall('<b>.*?</b>','<b>b标\n签</b>', flags=re.S))
-
作用
扫描真个字符串string 并返回第一个pattern模式的成功匹配 匹配失败返回None(包含即可)
-
原型
def search(pattern, string, flags=0)
-
参数
pattern 正则表达式
string 要匹配的字符串
flags 修正符
-
修正符
re.I 不区分大小写匹配
re.M 多行匹配 影响到^ 和 $ 的功能
re.S 使.可以匹配换行符 匹配任意字符
-
实例
res = re.search('[a-z]', '131A3ab889s') print(res) print(res.span()) print(res.group()
-
作用
正则匹配成功 返回匹配对象
匹配失败 返回None
-
原型
def match(pattern, string, flags)
-
参数
pattern 正则匹配
string 匹配的字符串
flags 修正符
-
实例
res = re.match('\d{2}','123') print(res.group()) print(res.span())
-
注意
与search的区别
相同点:
都只匹配一次
不同点:
- search是在要匹配的字符串中 包含正则表达式的内容就可以
- match 必须第一位就开始匹配 否则匹配失败
-
概述
扫描整个字符串 并返回所有pattern所匹配的结果
-
原型
def findall(pattern, string, flags=0)
-
参数
pattern 正则表达式
string 匹配的字符串
flags 修正符
-
实例
res = re.findall('\d', '2huihhdasd912sd') # [2,9,1,2] res = re.findall('\d—+', '2huihhdasd912sd') # [2, 912]
-
注意
匹配多次
-
功能
与findall类似, 但是finditer返回的是迭代器
-
原型
def finditer(pattern, string, flags=0)
-
参数
pattern 正则表达式
string 匹配的字符串
flags 修正符
-
实例
import re res = re.finditer('\w', '12hsakda1') print(res) print(next(res)) for i in res: print(i)
-
概述
拆分字符串
-
原型
def split(patter, string, maxsplit=0, flags=0)
-
参数
pattern 正则表达式
string 要拆分的字符串
maxsplit 最大拆分次数 默认拆分全部
flags 修正符
-
实例
import re myStr = '23iidih\tdiausd\n89y9812hdas' # res = re.split('\s', myStr) res = re.split('\S', myStr) print(res)
-
功能
使用正则 对字符串进行匹配替换
-
函数
sub() 正则替换
subn() 正则替换 返回替换后的次数
-
原型
def sub(pattern, repl, string, count=0,flags=0) def subn(pattern, repl, string, count=0,flags=0)
-
参数
pattern 正则表达式
repl 替换的字符串
string 被替换的字符串
count 替换次数
flags 修正符
-
实例
# html = '<i>我是b标签</i><i>我是加粗标签</i>' # 将b标签换成i标签 res = re.sub("<b>", "<i>", html) res = re.sub("<b>(.*?)</b>", "<i>\\1</i>", html) print(res) print(re.sub('(\d{4})/(\d{2})/(\d{2})','\\2-\\3-\\1', '2021/08/26'))
-
贪婪模式
- .+ 匹配换行符以外的字符至少一次
- .* 匹配换行符以外的字符任意次
实例
res = re.search('<b>.+</b>', '<b></b><b>b标签</b>') res = re.search('<b>.*</b>', '<b>b标签</b><b>b标签</b><b>b标签</b><b>b标签</b>')
-
非贪婪模式
- .+? 匹配换行符以外的字符至少一次 拒绝贪婪
- .*? 匹配换行符以外的字符任意次 拒绝贪婪
实例
res = re.search('<b>.+?</b>', '<b>b标签</b><b>b标签</b>') res = re.search('<b>.*?</b>', '<b>b标签</b><b>b标签</b><b>b标签</b><b>b标签</b>')
-
概念
使用分组起名称的前提 使用() 子存储 将子存储的值起名称 起名称以后依然可以使用索引取值
-
实例
# res = re.search('\d', '1234') # res = re.search('(\d)', '1234') res = re.search('(?P<value>\d)', '1234') print(res.group(0)) print(res.group('value')) print(res.groups())
-
概念
如果你的正则表达式想使用多次 提供compile函数 将正则以及修正符编译为正则表达式对象 以便多次使用
-
compile() 函数
-
原型
def compile(pattern, flags=0)
-
作用
将pattern编译成正则的对象
-
参数
pattern 正则表达式
flags 修正符
-
flags修正符
re.I 不区分大小写
re.S 使.可以匹配换行符(.无敌的存在)
re.M 多行匹配
-
使用
import re pattern = re.compile('[a-z]', re.I) print(pattern, type(pattern)) res = pattern.search('abc') res = pattern.search('c') print(res)
-