python中的re模块
Python中re定制软件开发模块主要功能是通过是定制软件开发用来匹配处理字符串的
第一步:import re
定制软件开发导入该模块后,定制软件开发就可以使用该模块下的定制软件开发所有方法和属性
import re
- 1
re定制软件开发有很多的方法和属性
re 定制软件开发模块提供了不少有用的函数,定制软件开发用以匹配字符串,比如:
compile 函数
match 函数
search 函数
findall 函数
finditer 函数
函数
sub 函数
subn 函数
re 定制软件开发模块的一般使用步骤如下:
使用 compile 定制软件开发函数将定制软件开发正则表达式的字定制软件开发符串形式编译为一个 Pattern 对象
通过 Pattern 定制软件开发对象提供的一系列方法定制软件开发对文本进行匹配查找,定制软件开发获得匹配结果(一个 Match 对象)
最后使用 Match 定制软件开发对象提供的属性和方法获得信息,定制软件开发根据需要进行其他的操作
compile 函数
compile 定制软件开发函数用于编译正则表达式,生成一个 Pattern 对象,定制软件开发它的一般使用形式如下:
re.compile(pattern,flag=0)'''pattern: 正则模型falgs : 匹配模式,定制软件开发比如忽略大小写,定制软件开发多行模式等返回值: Pattern 对象'''
- 1
- 2
- 3
- 4
- 5
- 6
使用方法:
import re# 定制软件开发将正则表达式编译成 Pattern 对象 pattern = re.compile(r'\d+')
- 1
- 2
- 3
在上面,定制软件开发我们已将一个正则表达式编译成 Pattern 对象,接下来,定制软件开发我们就可以利用 pattern 定制软件开发的一系列方法对文本进定制软件开发行匹配查找了。Pattern 定制软件开发对象的一些常用方法主要有:
match 方法
search 方法
findall 方法
finditer 方法
split 方法
sub 方法
subn 方法
正则表达式re.compile()
compile()的定义:
compile(pattern, flags=0) Compile a regular expression pattern, returning a pattern object.
- 1
- 2
从compile()定制软件开发函数的定义中,可以看出返回的是一个匹配对象,它单独使用就没有任何意义,需要和findall(), search(), match()搭配使用。
compile()与findall()一起使用,返回一个列表。
import redef main(): content = 'Hello, I am Jerry, from Chongqing, a montain city, nice to meet you……' regex = re.compile('\w*o\w*') x = regex.findall(content) print(x)if __name__ == '__main__': main()# ['Hello', 'from', 'Chongqing', 'montain', 'to', 'you']
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
compile()与match()一起使用,可返回一个class、str、tuple,dict。
compile()与match()一起使用,可返回一个class、str、tuple,dict。 但是一定需要注意match(),从位置0开始匹配,匹配不到会返回None,返回None的时候就没有span/group属性了,并且与group使用,返回一个单词‘Hello’后匹配就会结束。
import redef main(): content = 'Hello, I am Jerry, from Chongqing, a montain city, nice to meet you……' regex = re.compile('\w*o\w*') y = regex.match(content) print(y) print(type(y)) print(y.group()) print(y.span()) print(y.groupdict())if __name__ == '__main__': main()# <_sre.SRE_Match object; span=(0, 5), match='Hello'># <class '_sre.SRE_Match'># Hello# (0, 5)# {}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
compile()与search()搭配使用
compile()与search()搭配使用, 返回的类型与match()差不多, 但是不同的是search(), 可以不从位置0开始匹配。但是匹配一个单词之后,匹配和match()一样,匹配就会结束。
import redef main(): content = 'Hello, I am Jerry, from Chongqing, a montain city, nice to meet you……' regex = re.compile('\w*o\w*') z = regex.search(content) print(z) print(type(z)) print(z.group()) print(z.span()) print(z.groupdict())if __name__ == '__main__': main()# <_sre.SRE_Match object; span=(0, 5), match='Hello'># <class '_sre.SRE_Match'># Hello# (0, 5)# {}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
隐藏的 compile 函数
正常情况下 我们使用re模块时,我们都是先调用re模块的complie函数生成成pattern对象,使用pattern对象调用相应的方法进行正则匹配。一般代码写成下面的样子。
import repattern = re.compile('正则表达式')text = '一段字符串'result = pattern.findall(text)
- 1
- 2
- 3
- 4
但是在Python里面,在大多数情况下真的不需要使用re.compile!,直接使用re.对应的方法(pattern, string, flags=0)就可以了其原因就是热模块将complie函数的调用放在了对应的方法(pattern, string, flags=0)中了。我们常用的正则表达式方法,无论是findall还是search还是sub还是match,其返回值全部都是这样写的:
_compile(pattern, flag).对应的方法(string)
- 1
查看源码:
def findall(pattern, string, flags=0): """Return a list of all non-overlapping matches in the string. If one or more capturing groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than one group. Empty matches are included in the result.""" return _compile(pattern, flags).findall(string)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
果然是这个样子。实际上我们常用的正则表达式方法,都已经自带了compile了!
一般情况下不需要先使用re.compile再调用正则表达式方法。
再看一下re.compile源码
def compile(pattern, flags=0): "Compile a regular expression pattern, returning a Pattern object." return _compile(pattern, flags)
- 1
- 2
- 3
也是调用 _compile(pattern, flags)返回pattern对象。
如果我有一百万条字符串,使用某一个正则表达式去匹配,那么我可以这样写代码:
texts = [包含一百万个字符串的列表]pattern = re.compile('正则表达式')for text in texts: pattern.search(text)
- 1
- 2
- 3
- 4
这个时候,re.compile只执行了1次,而如果你像下面这样写代码:
texts = [包含一百万个字符串的列表]for text in texts: re.search('正则表达式', text)
- 1
- 2
- 3
相当于你在底层对同一个正则表达式执行了100万次re.compile。是不是这样子呢?答案是:不是,
红框中的代码,说明了 _compile自带缓存。它会自动储存最多512条由type(pattern), pattern, flags)组成的Key,只要是同一个正则表达式,同一个flag,那么调用两次_compile时,第二次会直接读取缓存。
综上所述,再大多数情况下不需要手动调用re.compile,除非你的项目涉及到几百万以上的正则表达式查询。
re中的正则匹配函数
1、match()函数(以后常用)
match,从头匹配一个符合规则的字符串,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None
match(pattern, string, flags=0)# pattern: 正则模型# string : 要匹配的字符串# falgs : 匹配模式
- 1
- 2
- 3
- 4
import restr="hello egon bcd egon lge egon acd 19"r=re.match("h\w+",str) #match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None,非字母,汉字,数字及下划线分割print(r.group()) # 获取匹配到的所有结果,不管有没有分组将匹配到的全部拿出来print(r.groups()) # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果print(r.groupdict()) # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果# hello# ()# {}r2=re.match("h(\w+)",str) #match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回Noneprint(r2.group())print(r2.groups())print(r2.groupdict())# hello# ('ello',)# {}r3=re.match("(?P<n1>h)(?P<n2>\w+)",str) #?P<>定义组里匹配内容的key(键),<>里面写key名称,值就是匹配到的内容print(r3.group())print(r3.groups())print(r3.groupdict())# hello# ('h', 'ello')# {'n1': 'h', 'n2': 'ello'}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
2、search()函数
search,浏览全部字符串,匹配第一符合规则的字符串,浏览整个字符串去匹配第一个,未匹配成功返回None
search(pattern, string, flags=0)# pattern: 正则模型# string : 要匹配的字符串# falgs : 匹配模式
- 1
- 2
- 3
- 4
注意:match()函数 与 search()函数基本是一样的功能,不一样的就是match()匹配字符串开始位置的一个符合规则的字符串,search()是在字符串全局匹配第一个合规则的字符串
import restr="hello egon bcd egon lge egon acd 19"r=re.search("h\w+",str) #match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None,非字母,汉字,数字及下划线分割print(r.group()) # 获取匹配到的所有结果,不管有没有分组将匹配到的全部拿出来print(r.groups()) # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果print(r.groupdict()) # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果# hello# ()# {}r2=re.search("h(\w+)",str) #match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回Noneprint(r2.group())print(r2.groups())print(r2.groupdict())# hello# ('ello',)# {}r3=re.search("(?P<n1>h)(?P<n2>\w+)",str) #?P<>定义组里匹配内容的key(键),<>里面写key名称,值就是匹配到的内容print(r3.group())print(r3.groups())print(r3.groupdict())# hello# ('h', 'ello')# {'n1': 'h', 'n2': 'ello'}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
3、findall()函数
浏览全部字符串,匹配所有合规则的字符串,匹配到的字符串放到一个列表中,未匹配成功返回空列表
findall(pattern, string, flags=0)# pattern: 正则模型# string : 要匹配的字符串# falgs : 匹配模式
- 1
- 2
- 3
- 4
注意: 一旦匹配成,再次匹配,是从前一次匹配成功的,后面一位开始的,也可以理解为匹配成功的字符串,不在参与下次匹配
'''注意: 一旦匹配成,再次匹配,是从前一次匹配成功的,后面一位开始的,也可以理解为匹配成功的字符串,不在参与下次匹配'''import rer=re.findall("\d+\w\d+","a2b3c4d5") #浏览全部字符串,匹配所有合规则的字符串,匹配到的字符串方到一个列表中print(r)# ['2b3', '4d5'] #匹配成功的字符串,不再参与下次匹配,所以3c4也符合规则但是没有匹配到
- 1
- 2
- 3
- 4
- 5
- 6
- 7
注意:如果没写匹配规则,也就是空规则,返回的是一个比原始字符串多一位的,空字符串列表
'''注意:如果没写匹配规则,也就是空规则,返回的是一个比原始字符串多一位的,空字符串列表'''import rer=re.findall("","a2b3c4d5") #浏览全部字符串,匹配所有合规则的字符串,匹配到的字符串方到一个列表中print(r)# ['', '', '', '', '', '', '', '', ''] #如果没有写匹配规则,也就是空规则,返回的是一个比原始字符串多一位的空字符串列表,如上是8个字符,返回是9个空字符
- 1
- 2
- 3
- 4
- 5
- 6
- 7
注意:正则匹配到空字符的情况,如果规则里只有一个组,而组后面是就表示组里的内容可以是0个或者多过,这样组里就有了两个意思,一个意思是匹配组里的内容,二个意思是匹配组里0内容(即是空白)所以尽量避免用否则会有可能匹配出空字符串
注意:正则只拿组里最后一位,如果规则里只有一个组,匹配到的字符串里在拿组内容是,拿的是匹配到的内容最后一位
'''注意:正则匹配到空字符的情况,如果规则里只有一个组,而组后面是*就表示组里的内容可以是0个或者多过,这样组里就有了两个意思,一个意思是匹配组里的内容,二个意思是匹配组里0内容(即是空白)所以尽量避免用*否则会有可能匹配出空字符串注意:正则只拿组里最后一位,如果规则里只有一个组,匹配到的字符串里在拿组内容是,拿的是匹配到的内容最后一位'''import rer=re.findall("(ca)*","ca2b3caa4d5") #浏览全部字符串,匹配所有合规则的字符串,匹配到的字符串方到一个列表中print(r)# ['ca', '', '', '', 'ca', '', '', '', '', '']#用*号会匹配出空字符
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
无分组:匹配所有合规则的字符串,匹配到的字符串放到一个列表中
'''无分组:匹配所有合规则的字符串,匹配到的字符串放到一个列表中'''import rer=re.findall("a\w+","ca2b3 caa4d5") #浏览全部字符串,匹配所有合规则的字符串,匹配到的字符串方到一个列表中print(r)# ['a2b3', 'aa4d5']#匹配所有合规则的字符串,匹配到的字符串放入列表
- 1
- 2
- 3
- 4
- 5
- 6
- 7
有分组:只将匹配到的字符串里,组的部分放到列表里返回,相当于groups()方法
'''有分组:只将匹配到的字符串里,组的部分放到列表里返回,相当于groups()方法'''import rer=re.findall("a(\w+)","ca2b3 caa4d5") #有分组:只将匹配到的字符串里,组的部分放到列表里返回print(r)# ['2b3', 'a4d5']#返回匹配到组里的内容返回
- 1
- 2
- 3
- 4
- 5
- 6
- 7
多个分组:只将匹配到的字符串里,组的部分放到一个元组中,最后将所有元组放到一个列表里返
相当于在group()结果里再将组的部分,分别,拿出来放入一个元组,最后将所有元组放入一个列表返回
'''多个分组:只将匹配到的字符串里,组的部分放到一个元组中,最后将所有元组放到一个列表里返相当于在group()结果里再将组的部分,分别,拿出来放入一个元组,最后将所有元组放入一个列表返回'''import rer=re.findall("(a)(\w+)","ca2b3 caa4d5") #有多分组:只将匹配到的字符串里,组的部分放到一个元组中,最后将所有元组放到一个列表里返回print(r)# [('a', '2b3'), ('a', 'a4d5')]#返回的是多维数组
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
分组中有分组:只将匹配到的字符串里,组的部分放到一个元组中,先将包含有组的组,看作一个整体也就是一个组,把这个整体组放入一个元组里,然后在把组里的组放入一个元组,最后将所有组放入一个列表返回
'''分组中有分组:只将匹配到的字符串里,组的部分放到一个元组中,先将包含有组的组,看作一个整体也就是一个组,把这个整体组放入一个元组里,然后在把组里的组放入一个元组,最后将所有组放入一个列表返回'''import rer=re.findall("(a)(\w+(b))","ca2b3 caa4b5") #分组中有分组:只将匹配到的字符串里,组的部分放到一个元组中,先将包含有组的组,看作一个整体也就是一个组,把这个整体组放入一个元组里,然后在把组里的组放入一个元组,最后将所有组放入一个列表返回print(r)# [('a', '2b', 'b'), ('a', 'a4b', 'b')]#返回的是多维数组
- 1
- 2
- 3
- 4
- 5
- 6
- 7
?:在有分组的情况下findall()函数,不只拿分组里的字符串,拿所有匹配到的字符串,注意?:只用于不是返回正则对象的函数如findall()
'''?:在有分组的情况下findall()函数,不只拿分组里的字符串,拿所有匹配到的字符串,注意?:只用于不是返回正则对象的函数如findall()'''import rer=re.findall("a(?:\w+)","a2b3 a4b5 edd") #?:在有分组的情况下,不只拿分组里的字符串,拿所有匹配到的字符串,注意?:只用于不是返回正则对象的函数如findall()print(r)# ['a2b3', 'a4b5']
- 1
- 2
- 3
- 4
- 5
- 6
- 7
4、split()函数
根据正则匹配分割字符串,返回分割后的一个列表
split(pattern, string, maxsplit=0, flags=0)# pattern: 正则模型# string : 要匹配的字符串# maxsplit:指定分割个数# flags : 匹配模式
- 1
- 2
- 3
- 4
- 5
import rer=re.split("a\w","sdfadfdfadsfsfafsff")print(r)r2=re.split("a\w","sdfadfdfadsfsfafsff",maxsplit=2)print(r2)# ['sdf', 'fdf', 'sfsf', 'sff']# ['sdf', 'fdf', 'sfsfafsff']
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
5、 sub()函数
替换匹配成功的指定位置字符串
sub(pattern, repl, string, count=0, flags=0)# pattern: 正则模型# repl : 要替换的字符串# string : 要匹配的字符串# count : 指定匹配个数# flags : 匹配模式
- 1
- 2
- 3
- 4
- 5
- 6
import rer=re.sub("a\w","替换","sdfadfdfadsfsfafsff")print(r)# sdf替换fdf替换sfsf替换sff
- 1
- 2
- 3
- 4
- 5
6、subn()函数
替换匹配成功的指定位置字符串,并且返回替换次数,可以用两个变量分别接受
subn(pattern, repl, string, count=0, flags=0)# pattern: 正则模型# repl : 要替换的字符串# string : 要匹配的字符串# count : 指定匹配个数# flags : 匹配模式
- 1
- 2
- 3
- 4
- 5
- 6
import rea,b=re.subn("a\w","替换","sdfadfdfadsfsfafsff") #替换匹配成功的指定位置字符串,并且返回替换次数,可以用两个变量分别接受print(a) #返回替换后的字符串print(b) #返回替换次数# sdf替换fdf替换sfsf替换sff# 3
- 1
- 2
- 3
- 4
- 5
- 6
- 7
参考资料