在一个简单的python正则表达式中可选分组

时间:2012-11-07 13:12:19

标签: python regex regex-group

我想要做的就是在字符串中搜索两个连续数字的实例。如果找到这样的实例,我想将其分组,否则为特定组返回none。我认为这是微不足道的,但我无法理解我哪里出错了。在下面的示例中,删除可选(?)字符可以获取数字,但是在没有数字的字符串中,r计算为None,因此r.groups()会抛出异常。

p = re.compile(r'(\d{2})?')
r = p.search('wqddsel78ffgr')
print r.groups()
>>>(None, )    # why not ('78', )?

# --- update/clarification --- #

感谢您的回答,但所给出的解释让我更加明智。这是另一个确切地指出我不理解的东西。

pattern = re.compile(r'z.*(A)?')
_string = "aazaa90aabcdefA"
result = pattern.search(_string)
result.group()
>>> zaa90aabcdefA
result.groups()
>>> (None, )

我理解为什么result.group()会产生结果,但为什么result.groups()不会产生('A', )?我认为它的工作方式如下:一旦正则表达式点击z,它就会使用.*匹配到行尾。尽管.*匹配了所有内容,但正则表达式引擎知道它通过了一个可选组,并且因为?意味着它会尝试匹配,如果它可以,它应该向后工作以尝试匹配。将?替换为+会返回('A', )。这表明?如果没有必要就不会尝试和匹配,但这似乎与我在这个主题上所阅读的大部分内容形成鲜明对比(特别是J. Friedl的优秀书)。

5 个答案:

答案 0 :(得分:1)

这对我有用:

p = re.compile('\D*(\d{2})?')
r = p.search('wqddsel78ffgr')
print r.groups()  # ('78',)

r = p.search('wqddselffgr')
print r.groups()  # (None,)

答案 1 :(得分:0)

使用正则表达式

(\d{2}|(?!.*\d{2}))

(见this demo

如果您想确定有2个连续数字而不是3个或更多,请使用

((?<!\d)\d{2}(?!\d)|(?!.*(?<!\d)\d{2}(?!\d)))

(见this demo

答案 2 :(得分:0)

?使你的正则表达式匹配空字符串。如果省略它,你可以检查结果如下:

p = re.compile(r'(\d{2})')
r = p.search('wqddsel78ffgr')
print r.groups() if r else ('',)

答案 3 :(得分:0)

请记住,您可以使用findall()轻松搜索字符串中RE的所有匹配项:

re.findall(r'\d{2}', 'wqddsel78ffgr') # => ['78']

如果您不需要匹配发生的位置,这似乎是一种更简单的方法来完成您正在做的事情。

答案 4 :(得分:-1)

? - 重复0或1次。所以正则表达式处理器首先尝试找到0次重复,然后......找到它:)