我试图抓住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 ']
答案 0 :(得分:0)
答案 1 :(得分:0)
请注意,|
在字符类中不会充当OR
。它会按字面意思匹配|
。这里的另一个问题是,findall
的行为是返回匹配,除非存在一个群组(尽管python's documentation并不真正使这个明确):
从左到右扫描字符串,并按找到的顺序返回匹配项。 如果模式中存在一个或多个组,请返回组列表
这就是为什么你得到第一个捕获组的结果,这是Caps
的最后一个大写起始字。
简单的解决方案是将您的捕获组更改为非捕获组。我还将开头的空间更改为\b
,以便不匹配额外的空格(我认为你打算计划修剪)。
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))
\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}(?= |$)