Python正则表达式返回匹配的最后一个字符的额外捕获组

时间:2015-11-27 22:28:16

标签: python regex string capture-group

我正在尝试创建一个正则表达式,它将接受字符串并将它们分成三组:(1)字符串开头的任何一个特定的单词列表。 (2)字符串末尾的特定单词列表中的任何一个。 (3)这两场比赛之间的所有字母/空格。

举个例子,我将使用以下两个字符串:

'There was a cat in the house yesterday'
'Did you see a cat in the house today'

我希望将字符串分解为捕获组,以便匹配对象m.groups()将分别为每个字符串返回以下内容:

('There', ' was a cat in the house ', 'yesterday')
('Did', ' you see a cat in the house ', 'today')

最初,我想出了以下正则表达式:

r = re.compile('^(There|Did) ( |[A-Za-z])+ (today|yesterday)$')

但是这会返回:

('There', 'e', 'yesterday')
('Did', 'e', 'today')

所以它只给了我中间组中匹配的最后一个字符。我了解到这并不起作用,因为捕获组只会返回匹配的最后一次迭代。所以我将括号放在中间捕获组周围,如下所示:

r = re.compile('^(There|Did) (( |[A-Za-z])+) (today|yesterday)$')

但是现在,虽然它确实至少捕获了中间组,但它也会返回一个额外的" e" m.groups()中的字符,即:

('There', 'was a cat in the house', 'e', 'yesterday')

...虽然我觉得这与回溯有关,但我无法弄清楚它为什么会发生。有人可以向我解释为什么我得到这个结果,以及我如何能得到预期的结果?

3 个答案:

答案 0 :(得分:1)

您可以使用匹配任何字符的.(点)运算符替换中间捕获组,然后使用*(星号)来简化当前正则表达式并获得正确的行为运算符重复匹配任何字符:

import re

s1 = 'There was a cat in the house yesterday'
s2 = 'Did you see a cat in the house today'

x = re.compile("(There|Did)(.*)(today|yesterday)")
g1 = x.search(s1).groups()
g2 = x.search(s2).groups()

print(g1)
print(g2)

生成此输出:

  

('那里','房子里有一只猫','昨天')
  ('做','你看到房子里有一只猫','今天')

答案 1 :(得分:1)

  

重复捕获组仅捕获最后一次迭代。放一个   捕获重复组周围的组以捕获所有迭代或   如果您对此不感兴趣,请使用非捕获组   数据

来源https://regex101.com/

以下是正常工作:

^(There|Did) ([ A-Za-z]+) (today|yesterday)$

答案 2 :(得分:1)

 r = re.compile('^(There|Did) (( |[A-Za-z])+) (today|yesterday)$')
                               ^ ^        ^
你有一些不必要的东西。拿出那些并在你的中间组中包含空格:

r = re.compile('^(There|Did) ([A-Za-z ]+) (today|yesterday)$')
                                     ^ space

实施例

>>> r = re.compile('^(There|Did) ([A-Za-z ]+) (today|yesterday)$')
>>> r.search('There was a a cat in the hosue yesterday').groups()
('There', 'was a a cat in the hosue', 'yesterday')

此外,如果您希望空格成为中间(第二)组的一部分,请取出捕获组之间的空格