python re模块 匹配中文_python处理文本文件——re模块

本文介绍了Python中的re模块,用于处理正则表达式。re模块提供了如match、search、fullmatch、findall、split、sub等方法,详细解析了它们的功能和区别,并展示了编译正则表达式、匹配对象的方法。此外,还提到编译正则表达式的行为可以通过标志值改变,以及匹配对象的属性和方法,如group、groups、start、end等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

c29266a5c8315d1308c7fa6b22b1f136.png

上一次在「正则表达式」一文中分享了正则表达式的基础内容,让大家了解到正则表达式的强大功能。

python自1.5版本起增加了re模块,re模块中提供了一些方法,可以方便在python语言中使用正则表达式,re模块使python语言拥有全部的正则表达式功能。

re模块的方法

python语言中把函数提供的功能叫做方法,re模块提供了各种各样的正则表达式方法。

re.match(pattern, string, flags=0)方法:如果string开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的匹配对象。如果没有匹配,就返回None.

>>> import re
>>> print(re.match('abc', 'abcdef').group())  # 匹配到开头
abc
>>> print(re.match('abc', 'defabc').group())  # 未未匹配开头,返回None
None

re.search(pattern, string, flags=0)方法:扫描整个字符串找到匹配样式的第一个位置(一旦匹配成功则停止匹配),并返回一个相应的匹配对象。如果没有匹配,就返回None.

>>> import re
>>> print(re.search('d+', 'ab12cd236ef').group())  # 返回第一个匹配
12
>>> print(re.search('d+', 'abcd236ef').group())  # 返回第一个匹配
236

re.match与re.search的区别:re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None,而re.search匹配整个字符串,直到找到一个匹配对象为止。

re.fullmatch(pattern, string, flags=0)方法:如果整个string匹配到正则表达式样式,就返回一个相应的匹配对象 ,否则就返回None.

>>> print(re.fullmatch('d+', 'ab12cd236ef'))  # 未匹配成功
None
>>> print(re.fullmatch('d+', '236'))  # 匹配整个字符串
<re.Match object; span=(0, 3), match='236'>

re.findall(pattern, string, flags=0)方法:搜索string,以列表的形式返回全部能匹配到的字串,对string从左到右进行扫描,按找到的顺序返回。

import re
>>> print(re.findall('(w=2u).*(l=1u)', 'n33 w=2u m=2 l=1u'))  # 分组
[('w=2u', 'l=1u')]
>>> print(re.findall('d+', 'ab12cd236ef12'))  # 匹配所有
['12', '236', '12']

如果样式里存在一到多个组,就返回一个组合列表;如果样式里有超过一个组合的话就是一个元组的列。re.split(pattern, string, maxsplit=0, flags=0)方法:用pattern分开string,如果在pattern中捕获到括号,那么所有的组里的文字也会包含在列表里。

import re
>>> print(re.split('d+', 'ab12cd236ef5678'))  # 使用数字分割
['ab', 'cd', 'ef', '']
>>> print(re.split('d+', 'ab12cd236ef'))  # 使用数字分割
['ab', 'cd', 'ef']
>>> print(re.split('(d+)', 'ab12cd236ef5678'))  # 分组
['ab', '12', 'cd', '236', 'ef', '5678', '']
>>> print(re.split('(d+)', 'ab12cd236ef'))  # 分组
['ab', '12', 'cd', '236', 'ef']

如果maxsplit非零,最多进行maxsplit次分隔,剩下的字符全部返回到列表的最后一个元素。

import re
>>> print(re.split('d+', 'ab12cd236ef5678', 2))  # 指定次数
['ab', 'cd', 'ef5678']

re.sub(pattern, repl, string, count=0, flags=0):使用repl替换string中每一个匹配的子串后返回替换后的字符串。可选参数count是要替换的最大次数,count必须是非负整数,如果忽略这个参数,或者设置为0,所有的匹配都会被替换。

import re
>>> print(re.sub(r'd+', ',', 'ab12cd236ef5678'))
ab,cd,ef,
>>> print(re.sub(r'(w=2u)(.*)(l=1u)', r'1*0.923*0.8', 'n33 w=2u m=2 l=1u'))
n33 w=2u*0.9 m=2 l=1u*0.8

repl可以是字符串或函数,如为字符串,则其中任何反斜杠转义序列都会被处理。也就是说,n会被转换为一个换行符,r会被转换为一个回车附,依此类推。re.sub()方法用来实现电路设计中网表替换功能十分方便,可以按照需要替换器件参数,会经常使用。re.subn(pattern, repl, string, count=0, flags=0):行为与re.sub()相同,但是返回一个元组 (新的替换字符串,替换次数)。

import re
>>> print(re.subn(r'd+', ',', 'ab12cd236ef5678'))
('ab,cd,ef,', 3)

以上是re模块常用的方法,还有个别不常用的方法如果有需要可以参考re模块的官方文档

编译正则表达式

绝大部分的正则表达式在使用前,总是会先将正则表达式编译,之后再进行操作,re模块提供re.compile(pattern, flags=0)方法将正则表达式的样式编译为一个正则表达式对象 (RegexObject).

import re
>>> pattern = re.compile(r'd+')
>>> print(type(pattern))
<class 're.Pattern'>

编译的正则表达式返回一个正则表达式对象可以用于匹配,这个对象的方法包括match(), search()以及其它方法等,与re模块的函数使用很类似,详细描述可以参考下面表格内容。

正则表达式对象的方法

方法描述
pattern.search(string[,pos[, endpos]])扫描整个string寻找第一个匹配的位置,并返回一个相应的匹配对象。
pattern.match(string[,pos[, endpos]])如果string开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的匹配对象。
pattern.fullmatch(string[,pos[, endpos]])如果整个string匹配这个正则表达式,就返回一个相应的匹配对象。
pattern.split(string,maxsplit=0)等价于split()函数,使用了编译后的样式。
pattern.findall(string[,pos[, endpos]])类似函数findall(),使用了编译后样式,可以接收可选参数。
pattern.sub(repl,string, count=0)等价于sub() 函数,使用了编译后的样式。
pattern.subn(repl, string, count=0)等价于subn()函数,使用了编译后的样式。
pattern.groups捕获组合的数量。
pattern.pattern编译对象的原始样式字符串。

以上方法中可选参数pos给出了字符串中开始搜索的位置索引,默认为0。可选参数endpos限定了字符串搜索的结束,它假定字符串长度endpos, 所以只有从pos到endpos-1的字符会被匹配。如果endpos小于pos,就不会有匹配产生。

import re
>>> pattern = re.compile(r'd+')
>>> pattern.search('ab12dc236ef5678').group()
'12'
>>> pattern.match('12dc236ef5678').group()
'12'
>>> pattern.fullmatch('5678').group()
'5678'
>>> pattern.findall('ab12dc236ef5678')
['12', '236', '5678']
>>> pattern.split('ab12dc236ef5678')
['ab', 'dc', 'ef', '']
>>> pattern.sub(',', 'ab12dc236ef5678')
'ab,dc,ef,'

正则表达式的编译行为可以通过指定标记的值来改变,通过指定标记值可以控制匹配的模式,多个标志值可以通过位操作符OR( | )来指定。

编译行为修饰符

修饰符描述
re.A让w, W, b, B, d, D, s 和 S 只匹配ASCII,而不是Unicode.
re.DEBUG显示编译时的debug信息。
re.I使匹配对大小写不敏感
re.L由做本地化识别匹配,不推荐使用。
re.M多行匹配,影响^和$.
re.S使.匹配包括换行在内的所有字符。
re.X允许表达式分段和添加注释,以便将正则表达式写得更易于理解。

匹配对象的方法

使用match()或者search()方法(无论使用编译的样式还是未编译的样式)返回值是一个匹配对象

如果没有匹配的话match()和search()返回None ,如果匹配成功,匹配对象总是有一个布尔值True,匹配对象支持以下方法和属性:

Match.group([group1, ...]):返回一个或者多个匹配的子组。如果只有一个参数,结果就是一个字符串,如果有多个参数,结果就是一个元组(每个参数对应一个项),如果没有参数,整个匹配都被返回。如果一个组号是负数,或者大于样式中定义的组数,一个IndexError索引错误就raise。

import re
>>> pattern = re.compile(r'(d+).*?(d+).*?(d+)')  # 非贪婪匹配
>>> match_pattern = pattern.search('ab12dc236ef5678')  # 分组
>>> match_pattern.groups()
('12', '236', '5678')
>>> match_pattern.group(0)
'12dc236ef5678'
>>> match_pattern.group(1)  # 第1个匹配
'12'
>>> match_pattern.group(3)  # 第3个匹配
'5678'
>>> match_pattern.group(2, 3)  # 第2个和3个匹配
('236', '5678')

如果正则表达式使用了(?P<name>…)语法,groupN参数就也可能是命名组的名字。如果一个参数在样式中未定义,一个 IndexError就raise。

import re
>>> pattern = re.compile(r'(?P<first>d+).*?(?P<second>d+).*?(?P<last>d+)')  # 非贪婪匹配,为分组命名
>>> match_pattern = pattern.search('ab12dc236ef5678')
>>> match_pattern.group('second')  # 选择分组
'236'

Match.groups(default=None):返回一个元组,包含所有匹配的子组,在样式中出现的从1到任意多的组合。default参数用于不参与匹配的情况,默认为None。

import re
>>> pattern = re.search(r'(d+).*?(d+).*?(d+)', 'ab12dc236ef5678')
>>> pattern.group(2)
'236'
>>> pattern.groups()
('12', '236', '5678')

Match.groupdict(default=None):返回一个字典,包含了所有的命名子组,key就是组名,default参数用于不参与匹配的组合,默认为None。例如:

import re
>>> pattern = re.compile(r'(?P<first>d+).*?(?P<second>d+).*?(?P<last>d+)')  # 非贪婪匹配,为分组命名
>>> match_pattern = pattern.search('ab12dc236ef5678')
>>> match_pattern.groupdict()  # 返回字典
{'first': '12', 'second': '236', 'last': '5678'}

Match.start([group]),Match.end([group]):返回group匹配到的字串的开始和结束索引。group默认为0(意思是整个匹配的子串)。

import re
>>> pattern = re.compile(r'(d+).*?(d+).*?(d+)')
>>> match_pattern = pattern.search('ab12dc236ef5678')
>>> match_pattern.end()
15
>>> match_pattern.start()
2

Match.span([group]):对于一个匹配m ,返回一个二元组 (m.start(group), m.end(group)) 。如果group没有在这个匹配中,就返回 (-1, -1) 。group默认为(0意思是整个匹配)。

import re
>>> pattern = re.compile(r'(d+).*?(d+).*?(d+)')
>>> match_pattern = pattern.search('ab12dc236ef5678')
>>> match_pattern.span(2)
(6, 9)

Match.pos,Match.endpos:返回正则引擎在字符串中搜索一个匹配的索引位置。

import re
>>> pattern = re.compile(r'(d+).*?(d+).*?(d+)')
>>> match_pattern = pattern.search('ab12dc236ef5678')
>>> match_pattern.pos  # 匹配从字符串头开始
0
>>> match_pattern.endpos  # 匹配到字符串尾结束
15

Match.lastindex:捕获组的最后一个匹配的整数索引值,如果没有匹配产生,则为None.

import re
>>> pattern = re.compile(r'(d+).*?(d+).*?(d+)')
>>> match_pattern = pattern.search('ab12dc236ef5678')
>>> match_pattern.lastindex
3

Match.lastgroup:最后一个匹配的命名组名字,如果没有产生匹配则为None.Match.re:返回产生这个实例的正则对象,这个实例是由正则对象的 match()或search()方法产生的。Match.string:传递到match()或search()方法的字符串。

import re
>>> pattern = re.compile(r'(?P<first>d+).*?(?P<second>d+).*?(?P<last>d+)')
>>> match_pattern = pattern.search('ab12dc236ef5678')
>>> match_pattern.lastgroup
'last'
>>> match_pattern.re
re.compile('(?P<first>d+).*?(?P<second>d+).*?(?P<last>d+)')
>>> match_pattern.string
'ab12dc236ef5678'

以上示例小目同学在python 3.7版本验证过,部分方法可能涉python版本问题,如有问题可以「在文章评论处」讨论。

re模块的有关内容也可以参考官方手册,有更详细的示例和解释,如有异议请以官方手册为准

除了官方提供的re模块外,还可以使用第三方模块:regex,与re模块兼容, 同时还提供了额外的功能和更全面的Unicode支持。对于大多数用户来说re模块已经满足需要,这里不对regex模块做介绍。

简介

作者:小目(wx:student_xiaomu)

微信公众号:ICSkillSharing,是一个共同学习的平台,分享最新IT类资讯、原创内容、IC中脚本语言的教程与使用心得、模拟IC新手在学习过程中遇到的问题等,与大家一起成长进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值