第二十一天python3 python的正则表达式re模块学习

python的正则表达式
python使用re模块提供了正则表达式处理的能力;

模式修正符

也叫正则修饰符,模式修正符就是给正则模式增强或增加功能的。

修正符 re模块提供的变量 描述
i re.I 使模式对大小写不敏感,不区分大小写。
x re.X 忽略表达式中的空白字符。
m re.M 使模式在多行文本中可以多个行头和行尾,影响^和$。
s re.S 让通配符“.”可以代替任意原子,包括换行符\n在内。
复制代码
import re
text = """
<12
>
 
 <x
 yz> 
 
 <!@#$%> 
 
 <1a!#
 e2> 
 
 <>
"""
ret1 = re.findall("<.*?>", text, re.S)
print(ret1)
"""
执行结果:
['<12\n>', '<x\n yz>', '<!@#$%>', '<1a!#\n e2>', '<>']
默认“.”是不会匹配换行符的,当添加上re.S之后,“.”就拥有了匹配任意字符的能力,包括换行符。
"""
复制代码
复制代码
re.M
re.MULTILINE	多行模式
re.S
re.DOTALL	单行模式
re.I
re.IGNORECASE	忽略大小写
re.X
re.VERBOSE	忽略表达式中的空白字符
使用|位或运算开启多种选项
#示例:n = re.match('b',s,re.M)
复制代码

编译

re.compile(pattern,flags=0)
设定flags,编译模式,返回正则表达式对象regex;
pattern就是正则表达式字符串,flags就是选项。正则表达式需要被编译,为了提高效率,这些编译后的结果被保存,下次使用同样的pattern的时候,就不需熬再次编译;

单次匹配

复制代码
re.match(pattern,string,flags=0)
regex.match(string[,pos[,endpos]])
match匹配从字符串的开头匹配,只匹配一次,返回match对象;

re.search(pattern,string,flag=0)
regex.search(string[,pos[,endpos]])
从头搜索直到第一个匹配,regex对象search方法可以重新设定开始位置和结束位置,返回match对象;

re.fullmatch(pattern,string,flags=0)
regex.fullmatch(string[,pos[,endpos]])
整个字符串和正则表达式匹配;
复制代码

 示例:

复制代码
import re
s = """bootle\nbag\nbig\napple"""
for i,c in enumerate(s,1):
    print((i-1,c),end='\n' if i%8 == 0 else ' ')

#执行结果:
(0, 'b') (1, 'o') (2, 'o') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b')
(8, 'a') (9, 'g') (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a')
(16, 'p') (17, 'p') (18, 'l') (19, 'e')
#之所以这样做是为了更好的理解match的边界问题;
复制代码
复制代码
n = re.match('b',s,re.M)
m = re.match('boot',s)
l = re.match('t',s)

print(n)
print(m)
print(l)
执行结果:
<_sre.SRE_Match object; span=(0, 1), match='b'>
<_sre.SRE_Match object; span=(0, 4), match='boot'>
None
#n和m都返回了一个match对象,并且给出了边界范围,是前包后不包;并且只匹配一次;
#l返回的结果是None,是因为match的特性就是从字符串的开头开始匹配;相当于^\w;
复制代码
复制代码
"(0, 'b') (1, 'o') (2, 'o') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b')
(8, 'a') (9, 'g') (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a')
(16, 'p') (17, 'p') (18, 'l') (19, 'e')"
#将需要匹配的字母"b"格式化
regex = re.compile('b')
#调用格式化后的match方法,并打印结果
print(regex.match(s))
print(regex.match(s,7))
print(regex.match(s,7,10))
print(regex.match(s,8))
#执行结果
#没有指定边界,默认从头开始找,默认匹配了第一个b;
<_sre.SRE_Match object; span=(0, 1), match='b'>
#指定了边界,把索引7作为开始,匹配到了第七个b;
<_sre.SRE_Match object; span=(7, 8), match='b'>
#指定了边界范围,指定7到10的索引范围,匹配到了7-10范围内的第一个b;
<_sre.SRE_Match object; span=(7, 8), match='b'>
#在指定的边界内,没有b字母,返回None;
None

#总结:对需要匹配的字符串进行编译(compile);相当于生成了关于match的一个编译对象;再去调用这个对象的match方法,就可以定义范围了;
复制代码
复制代码
"(0, 'b') (1, 'o') (2, 'o') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b')
(8, 'a') (9, 'g') (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a')
(16, 'p') (17, 'p') (18, 'l') (19, 'e')"
#对需要匹配的big进行格式化
regex = re.compile('big')
#调用格式化的fullmatch方法
print(regex.fullmatch(s,11))
print(regex.fullmatch(s,11,14))
print(regex.fullmatch(s,11,15))
#执行结果
None
<_sre.SRE_Match object; span=(11, 14), match='big'>
None
#从上面的执行结果可以看出fullmatch必须要给定明确的需要匹配字符串的边界范围,才有返回值;
复制代码

全文搜索

re.findall(pattern,string,flags=0)
regex.findall(string[,pos[,endpos]])
对整个字符串,从左至右匹配,返回所有匹配项的列表;

re.finditer(pattern,string,flags=0)
regex.finditer(string[,pos[,endpos]])
对真个字符串,从左至右匹配,返回所有匹配项,返回迭代器;
注意每次迭代返回的是match对象;

 示例:

复制代码
import re
s = """bootle\nbag\nbig\napple"""
for i,c in enumerate(s,1):
    print((i-1,c),end='\n' if i%8 == 0 else ' ')

#执行结果
#(0, 'b') (1, 'o') (2, 'o') (3, 't') (4, 'l') (5, 'e') (6, '\n') (7, 'b')
(8, 'a') (9, 'g') (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a')
(16, 'p') (17, 'p') (18, 'l') (19, 'e')
复制代码
n = re.findall('b',s)
m = re.findall('b\w',s)
print(n)
print(m)
# 执行结果
['b', 'b', 'b']
['bo', 'ba', 'bi']
复制代码
#锚定
regex = re.compile('^b\w',re.M)
regex1 = re.compile('^b\w',re.S)
print(regex.findall(s),"多行模式")
print(regex1.findall(s),"单行模式")
#执行结果
['bo', 'ba', 'bi'] 多行模式
['bo'] 单行模式
#不锚定
regex = re.compile('b\w',re.M)
regex1 = re.compile('b\w',re.S)
print(regex.findall(s),"多行模式")
print(regex1.findall(s),"单行模式")
#执行结果
['bo', 'ba', 'bi'] 多行模式
['bo', 'ba', 'bi'] 单行模式
复制代码
复制代码
#这地方要注意,当在finditer中用\b时,要加上r,防止\b被转译,如果不加r,则在finditer中\b表示的是ascii码中的含义,所以会有匹配不到的问题;
m = re.finditer(r'\bb',s)
print(m,type(m))

for r in m:
    print(r)

执行结果:
#finditer返回了一个可迭代对象;
<callable_iterator object at 0x0000022FE0280BA8> <class 'callable_iterator'>
#用for循环迭代这个可迭代对象,finditer不但可以匹配到字符串,而且何以打印出字符的边界;
<_sre.SRE_Match object; span=(0, 1), match='b'>
<_sre.SRE_Match object; span=(7, 8), match='b'>
<_sre.SRE_Match object; span=(11, 12), match='b'>
复制代码

匹配替换

re.sub(pattern,replacement,string,count=0,flags=0)
regex.sub(replacement,string,count=0)
使用pattern对字符串string进行匹配,对匹配项使用repl替换。replacement可以是string、bytes、function;

re.subn(pattern,replacement,string,count=0,flags=0)
regex.subn(replacement,string,count=0)
同sub返回一个元组(new_string、number_of_subs_made),并且告诉总共匹配了几次;

 示例:

import re
s = """bootle\nbag\nbig\napple"""

m = re.sub('b\w','AAA',s)
print(m)
执行结果:
AAAotle\nAAAg\nAAAg\napple
import re
s = """bootle\nbag\nbig\napple"""

n = re.sub('b\w',"AAA",s,count=1)
print(n)
#执行结果
AAAotle\nbag\nbig\napple
import re
s = """bootle\nbag\nbig\napple"""
regex = re.compile('b\w')
print(regex.sub('RRR',s,count=2))
执行结果:
RRRotle\nRRRg\nbig\napple
复制代码
import re
s = """bootle\nbag\nbig\napple"""

m = re.subn('b\w','AAA',s)
print(m)
regex = re.compile('b\w')
print(regex.subn('RRR',s,count=2))
print(regex.subn('RRR',s,count=10))

#执行结果
('AAAotle\nAAAg\nAAAg\napple', 3)
('RRRotle\nRRRg\nbig\napple', 2)
('RRRotle\nRRRg\nRRRg\napple', 3)
复制代码

分割字符串

re.split(pattern,string,maxsplit=0,flags=0)
re.split分割字符串
复制代码
import re
s = """01 bottle
02 bag
03      big1
100       able"""

result1 = re.split('[\s\d]+',s)
print(1,result1)

regex2 = re.compile('^[\s\d]+')
result2 = regex2.split(s)
print(2,result2)

regex3 = re.compile('^[\s\d]+',re.M)
result3 = regex3.split(s)
print(3,result3)

regex4 = re.compile('\s+\d+\s+')
result4 = regex4.split(s)
print(4,result4)
复制代码
#执行结果:
1 ['', 'bottle', 'bag', 'big', 'able']
2 ['', 'bottle\n02 bag\n03      big1\n100       able']
3 ['', 'bottle\n', 'bag\n', 'big1\n', 'able']
4 ['01 bottle', 'bag', 'big1', 'able']

分组

使用小括号的pattern捕获的数据被放到了组group中;
match、search函数可以返回match对象;findall返回字符串列表;finditer返回一个个match对象;

如果pattern中使用了分组,如果有匹配的结果,会在match对象中:
1、使用group(N)方式返回对应分组;1-N是对应的分组,0返回整个匹配的字符串;
2、如果使用了命名分组,可以使用group(‘name’)的方式取分组;
3、也可以使用groups()返回所有分组;
4、使用groupdict()返回所有命名的分组;

 示例:

复制代码
import re
s = """bootle\nbag\nbig\napple"""
print("分组")
regex = re.compile('(b\w+)')
result = regex.match(s)
print(type(result))
print(1,'match',result.groups())

result1 = regex.search(s,1)
print(2,'search',result1.groups())

print('命名分组')
regex2 = re.compile('(b\w+)\n(?P<name2>b\w+)\n(?P<name3>b\w+)')
result2 = regex2.match(s)
print(3,'match',result2)
print(4,result2.group(3),result2.group(2),result2.group(1))
print(5,result2.group(0).encode())
print(6,result2.group('name2'),result2.group('name3'))
print(7,result2.groups())
print(8,result2.groupdict())

print('#####')

result3 = regex.findall(s)
for x in result3:
    print(type(x),x)

regex3 = re.compile('(?P<head>b\w+)')
result3 = regex3.finditer(s)
for r in result3:
    print(type(r),r,r.group(),r.group('head'))
复制代码
复制代码
#执行结果
分组
<class '_sre.SRE_Match'>
1 match ('bootle',)
2 search ('bag',)
命名分组
3 match <_sre.SRE_Match object; span=(0, 14), match='bootle\nbag\nbig'>
4 big bag bootle
5 b'bootle\nbag\nbig'
6 bag big
7 ('bootle', 'bag', 'big')
8 {'name3': 'big', 'name2': 'bag'}
#####
<class 'str'> bootle
<class 'str'> bag
<class 'str'> big
<class '_sre.SRE_Match'> <_sre.SRE_Match object; span=(0, 6), match='bootle'> bootle bootle
<class '_sre.SRE_Match'> <_sre.SRE_Match object; span=(7, 10), match='bag'> bag bag
<class '_sre.SRE_Match'> <_sre.SRE_Match object; span=(11, 14), match='big'> big big
复制代码

 

posted @   潇湘神剑  阅读(85)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!
点击右上角即可分享
微信分享提示