Python正则表达式分组、命名分组与断言详解
本文详解Python正则表达式中的分组机制,包括无名分组与命名分组的语法及提取方法。深入解析后向引用实现字符串交换,以及前向/后向肯定与否定断言在复杂匹配中的应用,附带代码实例与实用工具推荐。
Python正则表达式分组、命名分组与断言详解
本文详细介绍Python中正则表达式分组的核心概念与具体用法,旨在帮助开发者掌握相关技巧。
正则表达式分组基础
正则表达式分组基础
分组是通过一对圆括号“()”将正则表达式包裹起来,匹配到的内容即构成一个分组。从正则表达式的左侧开始计数,遇到的第一个左括号“(”代表第一个分组,第二个左括号代表第二个分组,依此类推。此外,存在一个隐含的全局分组(编号为0),它代表整个正则表达式本身。
完成分组后,可以通过调用group(num)和groups()函数直接提取特定分组的内容。
例如,从代码中提取超链接的文本内容:
>>> s='<div><a href="https://support.google.com/chrome/?p=ui_hotword_search" rel="external nofollow" target="_blank">更多</a><p>dfsl</p></div>'
>>> print re.search(r'<a.*>(.*)</a>',s).group(1)
更多
或者采用另一种写法:
>>> print re.match(r'.*<a.*>(.*)</a>',s).group(1)
更多
基于上述分组匹配,我们可以获取目标子串。然而,当正则表达式中包含大量括号时,手动计数以确定所需子串对应的分组编号会变得繁琐。为此,Python引入了命名分组,相对于上述的无名分组,命名分组提供了更清晰的引用方式。
命名分组机制
命名分组机制
命名分组允许为具有默认编号的组指定一个别名。其语法格式如下:
(?P<name>正则表达式)#name是一个合法的标识符
例如,从字符串中提取IP地址:
>>> s = "ip='230.192.168.78',version='1.0.0'"
>>> re.search(r"ip='(?P<ip>\d+\.\d+\.\d+\.\d+).*", s)
>>> res.group('ip')#通过命名分组引用分组
'230.192.168.78'
后向引用技术
后向引用技术
在正则表达式中,圆括号“()”内的内容定义为一个组。随后,可以对整个组应用正则操作,例如重复操作符。需要注意的是,只有圆括号“()”用于形成组,方括号“[]”用于定义字符集,花括号“{}”用于定义重复次数。当使用“()”定义组后,正则引擎会按顺序将匹配的组存入缓存。若需在后续引用已匹配的内容,可使用“\数字”方式或通过命名分组“(?P=name)”进行引用。其中,\1表示引用第一个分组,\2表示第二个,以此类推,\n表示第n个组,而\0则引用整个被匹配的正则表达式。这些引用仅在正则表达式内部有效,常用于匹配重复字符串。例如:
#通过命名分组进行后向引用
>>> re.search(r'(?P<name>go)\s+(?P=name)\s+(?P=name)', 'go go go').group('name')
'go'
#通过默认分组编号进行后向引用
>>> re.search(r'(go)\s+\1\s+\1', 'go go go').group()
'go go go'
实现字符串位置交换:
>>> s = 'abc.xyz'
>>> re.sub(r'(.*)\.(.*)', r'\2.\1', s)
'xyz.abc'
前向肯定断言与后向肯定断言
前向肯定断言与后向肯定断言
前向肯定断言的语法结构为:
(?=pattern)
后向肯定断言的语法结构为:
(?<=pattern)
需要注意的是,若匹配过程需同时使用前向肯定断言和后向肯定断言,必须将后向肯定断言置于正则语句的前部,前向肯定断言置于后部,这表示匹配后向模式之后且前向模式之前的内容。例如,获取C语言代码中的注释内容:
>>> s1='''char *a="hello world"; char b='c'; /* this is comment */ int c=1; /* t
his is multiline comment */'''
>>> re.findall( r'(?<=/\*).+?(?=\*/)' , s1 ,re.M|re.S)
[' this is comment ', ' this is multiline comment ']
其中,(?<=/*)为后向肯定断言,表示匹配“/*”之后的内容;(?=*/)为前向肯定断言,表示匹配“*/”之前的内容。两者结合即定义了一个区间,因此后向断言需放在前向断言之前的位置。
前向否定断言与后向否定断言
前向否定断言与后向否定断言
前向否定断言的语法结构为:
(?!pattern)
后向否定断言的语法结构为:
(?<!pattern)
前向否定与后向否定的应用实例:
#提取不是.txt结尾的文件
>>> f1 = 'aaa.txt'
>>> re.findall(r'.*\..*$(?<!txt$)',f1)
[]
#提取不以数字开头的文件
>>> re.findall(r'^(?!\d+).*','1txt.txt')
[]
#提取不以数字开头不以py结尾的文件
>>> re.findall(r'^(?!\d+).+?\..*$(?<!py$)','test.py')
[]
>>> re.findall(r'^(?!\d+).+?\..*$(?<!py$)','test.txt')
['test.txt']
此外,推荐两款实用的正则表达式在线测试工具供参考:
JavaScript正则表达式在线测试工具: http://tools.jb51.net/regex/javascript
正则表达式在线生成工具: http://tools.jb51.net/regex/create_reg
如需了解更多Python相关知识,可查阅本站系列教程,包括《Python正则表达式用法总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》。
希望本文的内容对您的Python编程学习有所帮助。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













