【问题标题】:Capture all consecutive all-caps words with regex in python?在python中使用正则表达式捕获所有连续的全大写单词?
【发布时间】:2017-04-20 15:01:02
【问题描述】:

我正在尝试在 Python 中使用正则表达式匹配所有连续的大写单词/短语。鉴于以下情况:

    text = "The following words are ALL CAPS. The following word is in CAPS."

代码将返回:

    ALL CAPS, CAPS

我目前正在使用:

    matches = re.findall('[A-Z\s]+', text, re.DOTALL)

但这会返回:

    ['T', ' ', ' ', ' ', ' ALL CAPS', ' T', ' ', ' ', ' ', ' ', ' CAPS']

我显然不想要标点符号或“T”。我只想返回连续单词或仅包含所有大写字母的单个单词。

谢谢

【问题讨论】:

  • 当单词没有被ABC.DEF这样的空格分隔时,你会期待什么?
  • 为什么你使用re.DOTALL这个选项,因为你的图案中没有点?
  • 它只是从另一个命令中复制进来的。但它不会改变输出。对正则表达式非常陌生,所以肯定不会这样做。
  • 我很困惑,您的问题要求consecutive all-caps words,但您想要的结果示例表明您只是在寻找 any 全大写单词。
  • 应该更清楚——我想捕获所有大写的所有单词,但如果它们是连续的,我希望它们作为一个短语返回,而不是单个单词。

标签: python regex


【解决方案1】:

这个可以做的:

import re
text = "tHE following words aRe aLL CaPS. ThE following word Is in CAPS."
matches = re.findall(r"(\b(?:[A-Z]+[a-z]?[A-Z]*|[A-Z]*[a-z]?[A-Z]+)\b(?:\s+(?:[A-Z]+[a-z]?[A-Z]*|[A-Z]*[a-z]?[A-Z]+)\b)*)",text)
print matches

输出:

['tHE', 'aLL CaPS', 'ThE', 'Is', 'CAPS']

说明:

(           : start group 1
  \b        : word boundary
  (?:       : start non capture group
    [A-Z]+  : 1 or more capitals
    [a-z]?  : 0 or 1 small letter
    [A-Z]*  : 0 or more capitals
   |        : OR
    [A-Z]*  : 0 or more capitals
    [a-z]?  : 0 or 1 small letter
    [A-Z]+  : 1 or more capitals
  )         : end group
  \b        : word boundary
  (?:       : non capture group
    \s+     : 1 or more spaces
    (?:[A-Z]+[a-z]?[A-Z]*|[A-Z]*[a-z]?[A-Z]+) : same as above
    \b      : word boundary
  )*        : 0 or more time the non capture group
)           : end group 1

【讨论】:

  • 谢谢!接受了答案。这很完美。您是否有机会帮助在捕获的字符串中向 allow (不需要)一个小写字符添加标志?我认为需要一个小写字母就像'(?=.*[a-z])',但我想得到这样的短语/单词-'ALL CapS'或'CaPS',还有'ALL CAPS' , 大写字母'。再次感谢
  • @BHudson:单词必须以大写字母开头吗?字符串开头的The呢?
  • 它们不必以大写字母开头,但除一个字符外,所有字符都应大写。我有一个巨大的文件,其中名称全部大写,但许多拼写错误。我正在提取所有名称并将使用模糊匹配来更正它们。有些错误地只有一个小写字母。所以,我需要匹配 'tHE' 或 'TheE',而不是 'The'(我可能使用的是 'JOhN SMITh' 或 'jOHN SMiTH')。谢谢
  • 谢谢!完美的。欣赏解释。
  • 我见过的最好的正则表达式演练。干得好@Toto。
【解决方案2】:

您的正则表达式依赖于明确的条件(字母后的空格)。

matches = re.findall(r"([A-Z]+\s?[A-Z]+[^a-z0-9\W])",text)

如果没有尾随小写或非字母字符,则捕获 A 到 Z 重复。

【讨论】:

  • OP 说“ALL CAPS”应该是 1 个匹配组,而您错过了 A case 一词
  • @Tezra 已编辑以满足要求。
【解决方案3】:

保留您的正则表达式,您可以使用strip()filter

string = "The following words are ALL CAPS. The following word is in CAPS."
result = filter(None, [x.strip() for x in re.findall(r"\b[A-Z\s]+\b", string)])
# ['ALL CAPS', 'CAPS']

【讨论】:

    【解决方案4】:

    假设你想以一个字母开始和结束,并且只包含字母和空格

    \b([A-Z][A-Z\s]*[A-Z]|[A-Z])\b
    

    |[A-Z] 仅捕获 I 或 A

    【讨论】:

      猜你喜欢
      • 2013-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多