为什么正则表达式不能捕获最初的单词?蟒蛇

时间:2014-08-04 21:05:41

标签: python regex

为什么我的正则表达式不能在介词之前捕获单词?

我的正则表达式模式试图捕获在它们之后有介词的专有名词。 例如: •管理学院 - >学院 •McGraw Hill书籍基金会 - >成立

以下文字:

  

'管理学院创业部和麦格劳希尔向那些为研究生或本科教育开发和实施创业教育学创新的个人颁发年度奖。'

pp = r'[A-Z][A-Za-z]+\s+\b(for|of|in|by)\b(?=\s+[A-Z][A-Za-z]+)'

x2 = re.findall(pp,test)

x2

输出:

'的'

为什么不输出'Academy of'?

4 个答案:

答案 0 :(得分:3)

只需在介词前放置一个捕捉组:

pp = r'([A-Z][A-Za-z]+)\s+\b(for|of|in|by)\b(?=\s+[A-Z][A-Za-z]+)'

或者如果你想捕获整个单词/介词字符串:

pp = r'([A-Z][A-Za-z]+\s+\b(?:for|of|in|by))\b(?=\s+[A-Z][A-Za-z]+)'

答案 1 :(得分:3)

捕获组是括在括号( )中的正则表达式的一部分。它们用于从匹配表达式中提取特定部分。看起来你偶然遇到过它们,因为你正在使用一个匹配"","",""""或" by"。

如果您的表达式中有一个捕获组(如您的问题所示),re.findall将返回该组的匹配列表。目前,您在正则表达式的第一部分周围没有任何组。如果你想要捕获它,你还必须将它括在一些括号中:

pp=r'([A-Z][A-Za-z]+\s+\b(for|of|in|by))\b(?=\s+[A-Z][A-Za-z]+)'
#    ^                                 ^
re.findall(pp,test)

返回:

[('Academy of', 'of')]

现在re.findall已经返回了一个元组列表,因为现在有多个捕获组。元组的元素按组开始的顺序出现。

如果您不想与其他组匹配,可以将其更改为非捕获组:

(?:for|of|in|by)

然后,唯一可以捕获的是['Academy of']。虽然现在您只剩下一个捕获组,所以您可以完全省略括号,re.findall将返回与完整正则表达式匹配的任何内容。

pp=r'[A-Z][A-Za-z]+\s+\b(?:for|of|in|by)\b(?=\s+[A-Z][A-Za-z]+)'

答案 2 :(得分:2)

实际的正则表达式搜索正如您所期望的那样工作。让你沮丧的是,for|of|in|by周围的括号引入了一个捕获组。

来自re.findall() docs

  

如果模式中存在一个或多个组,则返回组列表。

以下是解决此问题的方法:

pp = r'[A-Z][A-Za-z]+\s+\b(?:for|of|in|by)\b(?=\s+[A-Z][A-Za-z]+)'
                           ^^

(?:...)non-capture group。有了这个,re.findall()将返回整个匹配。

答案 3 :(得分:1)

来自re.findall的文档:

  

如果模式中存在一个或多个组,则返回组列表;如果模式有多个组,这将是一个元组列表。

对于您的模式,您有一个捕获组(for|of|in|by)和一个非捕获组(?=\s+[A-Z][A-Za-z]+)(由于问号而未捕获)。

如果您想将'Academy of'作为单个字符串返回,只需使捕获组不捕获:

pp = r'[A-Z][A-Za-z]+\s+\b(?:for|of|in|by)\b(?=\s+[A-Z][A-Za-z]+)'
                           ^
re.findall(pp,test) # prints ['Academy of']