正则表达式匹配n个连续的大写单词

问题描述 投票:0回答:2

我试图捕获n个连续的大写单词。我目前的代码是

n=5 
a='This is a Five Gram With Five Caps and it also contains a Two Gram'
re.findall(' ([A-Z]+[a-z|A-Z]* ){n}',a)

返回以下内容:

['Caps ']

它识别出第五个连续的大写单词,但我希望它返回整个大写单词串。换一种说法:

[' Five Gram With Five Caps ']
regex python-3.6
2个回答
0
投票

请注意,|不会在角色类中充当OR。它会与字面上的|相匹配。另一个问题是findall的行为是返回比赛,除非存在一个组(尽管python's documentation并没有真正明确这一点):

从左到右扫描字符串,并按找到的顺序返回匹配项。如果模式中存在一个或多个组,则返回组列表

所以这就是为什么你得到第一个捕获组的结果,这是Caps的最后一个大写字母。

简单的解决方案是将捕获组更改为非捕获组。我也在开始时将空间更改为\b,以便不匹配额外的空格(我认为你打算计划修剪)。

See code in use here

import re

r = re.compile(r"\b(?:[A-Z][a-zA-Z]* ){5}")
s = "This is a Five Gram With Five Caps and it also contains a Two Gram"
print(r.findall(s))

See regex in use here

\b(?:[A-Z][a-zA-Z]* ){5}
  • \b将位置断言为单词边界
  • (?:[A-Z][a-zA-Z]* ?){5}完全匹配以下5次 [A-Z]匹配一个大写的ASCII字母一次 [a-zA-Z]*任意次数匹配任何ASCII字母 匹配一个空间

结果:['Five Gram With Five Caps ']

此外,您可以使用正则表达式\b\[A-Z\]\[a-zA-Z\]*(?: \[A-Z\]\[a-zA-Z\]*){4}\b。这将允许匹配字符串的开头/结尾以及中间的任何位置,而不会占用额外的空格。另一种选择可能包括(?:^|(?<= ))\[A-Z\]\[a-zA-Z\]*(?: \[A-Z\]\[a-zA-Z\]*){4}(?= |$)


0
投票

将整个模式包装在捕获组中:

(([A-Z]+[a-z|A-Z]* ){5})

Demo

© www.soinside.com 2019 - 2024. All rights reserved.