python re模块中的'[ab]+'是不是等于'(a|b)+'?

Posted

技术标签:

【中文标题】python re模块中的\'[ab]+\'是不是等于\'(a|b)+\'?【英文标题】:Does '[ab]+' equal '(a|b)+' in python re module?python re模块中的'[ab]+'是否等于'(a|b)+'? 【发布时间】:2012-09-02 22:15:48 【问题描述】:

我认为 pat1 = '[ab]' 和 pat2 = 'a|b' 在 Python(python2.7, windows) 're' 模块中作为正则表达式模式具有相同的功能。但是我对'[ab]+'和'(a|b)+'感到困惑,它们是否具有相同的功能,如果没有,您可以详细说明一下。

'''
Created on 2012-9-4

@author: melo
'''

import re
pat1 = '(a|b)+'
pat2 = '[ab]+'
text = '22ababbbaa33aaa44b55bb66abaa77babab88'

m1 = re.search(pat1, text)
m2 = re.search(pat2, text)
print 'search with pat1:', m1.group()
print 'search with pat2:', m2.group()

m11 = re.split(pat1, text)
m22 = re.split(pat2, text)
print 'split with pat1:', m11
print 'split with pat2:', m22

m111 = re.findall(pat1, text)
m222 = re.findall(pat2, text)
print 'findall with pat1:', m111
print 'findall with pat2:', m222

输出如下:

search with pat1: ababbbaa
search with pat2: ababbbaa
split with pat1: ['22', 'a', '33', 'a', '44', 'b', '55', 'b', '66', 'a', '77', 'b', '88']
split with pat2: ['22', '33', '44', '55', '66', '77', '88']
findall with pat1: ['a', 'a', 'b', 'b', 'a', 'b']
findall with pat2: ['ababbbaa', 'aaa', 'b', 'bb', 'abaa', 'babab']

为什么 'pat1' 和 'pat2' 不同,它们有什么区别? 'pat1' 实际可以匹配什么样的字符串?

【问题讨论】:

我可以在 Mac OS X 10.7.4 上使用 Python 2.7.1 确认该行为。我无法立即解释这种行为。 如果您将pat1 更改为((a|b)+) 然后重新运行测试,您会得到完全不同的输出。这与 () 在正则表达式中分组/捕获运算符有关。但我不完全确定是什么——而且我感觉有点懒,这就是为什么这是评论而不是答案。 @JonathanLeffler 是的,如果您将pat2 更改为'([ab]+)',您将获得相同的输出。那么谁能解释()的行为呢? @user1477871 我认为你的意思是你会得到与([ab])+ 相同的输出,而不是([ab]+)。有一个重要的区别。 @Wiseguy 是的,没错,你是对的。 【参考方案1】:

您在第一个模式中有一个捕获组。

根据the docs,

re.split() ... 如果在 pattern 中使用了捕获括号,那么模式中所有组的文本也会作为结果列表的一部分返回。 ...

尝试让组不被捕获,看看你是否得到了你期望的结果:

pat1 = '(?:a|b)+'

【讨论】:

此外,对于重复组,仅返回最后一次捕获。 re.findall() 有另一个区别:如果没有捕获组,则返回整个匹配项。否则,只返回捕获组的内容。

以上是关于python re模块中的'[ab]+'是不是等于'(a|b)+'?的主要内容,如果未能解决你的问题,请参考以下文章

Python的学习之旅———re 模块正则表达式

python中re time os sys模块

Python2.7-re模块

re 模块

re 模块中的正则表达式是不是支持单词边界 (\b)?

进阶第七课 Python模块之re