为什么python regex搜索方法不能始终如一地正确返回匹配的对象?

时间:2018-09-29 15:23:22

标签: python regex python-3.x regex-group

我正在对正则表达式课程进行练习题:

您如何编写与第一个单词是Alice,Bob或Carol的句子匹配的正则表达式;第二个单词要么是吃东西,宠物,要么是抛出东西。第三个单词是苹果,猫或棒球;句子以句号结尾?此正则表达式不区分大小写。它必须符合以下条件:

  • 爱丽丝吃苹果。
  • 鲍勃宠物猫。
  • 卡罗尔投了棒球。
  • 爱丽丝扔苹果。
  • BOB EATS CATS。

我的代码如下:

regex=re.compile(r'Alice|Bob|Carol\seats|pets|throws\sapples\.|cats\.|baseballs\.',re.IGNORECASE)
mo=regex.search(str)
ma=mo.group()

当我通过str ='BOB EATS CATS.''Alice throws Apples.'时,mo.group()仅分别返回'Bob''Alice',但我希望它能返回整个句子。

当我通过str='Carol throws baseballs.'时,mo.group()返回'baseballs.',这是最后一个匹配项。

我对为什么感到困惑

  • 对于我通过的前两个str示例,它返回了第一个匹配项('Bob''Alice'),而我通过的第三个str示例则返回了最后一个匹配项({{1} })?

  • 在所有3个str示例中,我不确定为什么'baseball'不会返回整个句子作为匹配项。即我期望mo.group()作为'Carol throws baseballs.'

  • 的输出

3 个答案:

答案 0 :(得分:1)

您需要告诉您的正则表达式以某种方式对选项列表进行分组,否则自然会认为这是一个庞大的列表,其中某些元素包含空格。最简单的方法是对每个单词使用捕获组:

regex=re.compile(r'(Alice|Bob|Carol)\s+(eats|pets|throws)\s+(apples|cats|baseballs)\.', re.IGNORECASE)

尾随期不应该是期权的一部分。如果由于某种原因不想使用捕获组(不会真正影响匹配的方式),则可以改用非捕获组。将(...)替换为(?:...)

您原来的正则表达式被解释为以下选项:

  • Alice
  • Bob
  • Carol\seats
  • pets
  • throws\sapples.
  • cats.
  • baseballs.

空格不会神奇地分开选项。希望您能看到为什么列表中除了Carol throws baseballs.之外没有baseballs.的任何元素。像Carol eats baseballs.这样的东西会匹配Carol eats

答案 1 :(得分:0)

您应该将所有单词分组

您的要求应如下所示:

regex = r'(?:Alice|Bob|Carol)\s(?:eats|pets|throws)\s(?:apples|cats|baseballs)\.'

请注意,我使用(?:)而不是(),因为分组仅出于逻辑目的

答案 2 :(得分:-1)

您也可以这样:

(\w{3,5}) (\w*) ([^f]\w+)