【问题标题】:Python regular expression is not matching all expected wordsPython 正则表达式不匹配所有预期的单词
【发布时间】:2015-11-04 03:17:16
【问题描述】:

在 regexr.com 上,我开发了一个匹配某些类型的专有名称的正则表达式。这是表达式:

\b([a-z]?[A-Z]+[\w]*[ ]*)+\b

您可以在现场看到许多示例,如预期的那样匹配 http://regexr.com/3bifh

例如从字符串 Moby Dick or the White Whale by Herman Melville 匹配 Moby DickWhite WhaleHerman Melville

我正在尝试在 Python 中重现这一点,但成功率较低。代码如下:

import re

text = "Moby Dick or the White Whale by Herman Melville"
print(re.findall(r"\b([a-z]?[A-Z]+[\w]*[ ]*)+\b", text))

输出是:

['Dick ', 'Whale ', 'Melville']

这仅匹配上面每个结果的最后一部分。 为什么表达式在 Python 中不起作用?

【问题讨论】:

  • regexpr.com 小提琴页面上突出显示的所有内容。
  • “可能是一个小写字母,然后是一个或多个大写字母,然后是可选的更多字母,以及可选的空格”——这个正则表达式基本上不是归结为\w+ 还是我遗漏了什么?
  • 你的意思是 r"\w+"?不,我正在尝试匹配专有名称/缩写,例如“United States”、“USA”、“Moby Dick”、“Edgar Allen Poe”或“iPhone”。关键部分是大写字母。
  • 我有点明白,但目前你的正则表达式是如此广泛,它几乎可以匹配任何字母字符串,最后有任意数量的空格,只要它在某处有一个大写字母 。此时仅检查 s != s.lower() 或类似名称可能会更有效。
  • 重点是,我需要匹配彼此跟随的标题大小写单词。比如,“Edgar Allen Poe”作为一个项目,而不是“Edgar”、“Allen”和“Poe”作为三个项目。

标签: python regex findall


【解决方案1】:

当多个组匹配时,正则表达式引擎只记住最后一个组。

你可以改用这个

 print (re.findall(r"\b((?:[a-z]?[A-Z]+[\w]*[ ]*)+)\b", text))

【讨论】:

  • 好,但我不想拆分匹配的部分。
  • @DrunkenMaster 已编辑。现在不需要split。您的原始正则表达式现在完好无损:P
【解决方案2】:

将捕获组转为非捕获组。

print(re.findall(r"\b(?:[a-z]?[A-Z]+[\w]*[ ]*)+\b", text))

here,它匹配第一部分但捕获第二部分。 re.findall 将优先考虑捕获,然后是匹配项。所以它会打印出第二部分。

如果您不想匹配尾随空格字符,请像打击一样改变您的模式。

r'\b[a-z]?[A-Z]+\w*(?: [a-z]?[A-Z]+\w*)+'

DEMO

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多