提问人:MojavePatroller 提问时间:11/1/2023 最后编辑:InSyncMojavePatroller 更新时间:11/1/2023 访问量:72
re.findall() 的模式行为,后跟一个捕获组,后跟一个量词 [duplicate]
re.findall()'s behavior for patterns with a single capturing group followed by a quantifier [duplicate]
问:
如果模式具有单个量化捕获组,则 re.findall() 似乎不会返回实际匹配项。
例如:
p1 = r"(apple)*"
t1 = "appleappleapple"
re.findall(p1, t1) # returns "['apple', '']"
而在
[i.group() for i in re.finditer(p1, t1)]
产生完全匹配,即['appleappleapple', '']
另一件让我感到困惑的事情是这种行为:
t2 = "appleapplebananaapplebanana"
re.findall(p1, t2) will return "['apple', '', '', '', '', '', '', 'apple', '', '', '', '', '', '', '']"
这些额外的空字符串究竟是从哪里来的?为什么 findall() 会在输入字符串末尾之前捕获它们?
答:
-1赞
Deepak Gupta
11/1/2023
#1
让我们首先尝试了解 * 和 () 是如何工作的。此正则表达式尝试将模式与“零个或多个前一个字符或组”匹配。
p1 = r"(banana)*"
t1 = "apple"
res = re.findall(p1, t1) # returns ['', '', '', '', '', '']
print(len(t1)) # returns 5
print(len(res)) #returns 6
现在,在从 len 返回后,我们知道为什么这些空白会出现,它试图与每个“前面的角色”和组匹配。这就是为什么它返回 6 个空字符串表示不匹配(5 个字符 + 1 个组)。
现在我们如何删除这些空字符串。好吧,我已经稍微玩了一下这个模式,这就是我发现的。删除 (.
p1 = r"apple*"
t1 = "appleappleapple"
res = re.findall(p1, t1) #returns ['apple', 'apple', 'apple']
也使用相同的模式
[i.group() for i in re.finditer(p1, t1)] # returns ['apple', 'apple', 'apple']
t2 = "appleapplebananaapplebanana"
re.findall(p1, t2) #returns ['apple', 'apple', 'apple']
0赞
Chirag Mehta
11/1/2023
#2
我认为@Deepak的回答并没有完全解决这个问题。
让我们检查第一个代码片段:
p1 = r"(apple)*"
t1 = "appleappleapple"
re.findall(p1, t1) # returns "['apple', '']"
让我们澄清一下我们的期望。我原以为上述代码片段的输出是 ['appleappleapple', '']。这是因为应该贪婪地匹配到最后,并且由于它只提供非重叠匹配,因此唯一的其他匹配应该是空字符串。findall
但是,为什么输出不同?
如文档中所述,如果字符串中存在一个或多个组,则返回的是组。这就是为什么你获得苹果作为匹配而不是苹果苹果的原因。
现在,关于第三个片段,我相信迪帕克的回答确实解决了这个问题。不过,为了完整起见,我也会在这里提到它:
t2 = "appleapplebananaapplebanana"
re.findall(p1, t2) will return "['apple', '', '', '', '', '', '', 'apple', '', '', '', '', '', '', '']"
由于您使用了 ,它将匹配该组的 0 次或多次出现。这就是获取所有这些空字符串的原因。*
评论