簡體   English   中英

Python正則表達式返回匹配的最后一個字符的額外捕獲組

[英]Python regular expression returning extra capture group for last character matched

我正在嘗試創建一個正則表達式,它將接受字符串並將它們分成三組:(1)字符串開頭的任何一個特定的單詞列表。 (2)字符串末尾的特定單詞列表中的任何一個。 (3)這兩個匹配之間的所有字母/空格。

作為一個例子,我將使用以下兩個字符串:

'There was a cat in the house yesterday'
'Did you see a cat in the house today'

我希望將字符串分解為捕獲組,以便匹配對象m.groups()將分別為每個字符串返回以下內容:

('There', ' was a cat in the house ', 'yesterday')
('Did', ' you see a cat in the house ', 'today')

最初,我想出了以下正則表達式:

r = re.compile('^(There|Did) ( |[A-Za-z])+ (today|yesterday)$')

但是這會返回:

('There', 'e', 'yesterday')
('Did', 'e', 'today')

所以它只給了我中間組中匹配的最后一個字符。 我了解到這不起作用,因為捕獲組只會返回匹配的最后一次迭代。 所以我將括號放在中間捕獲組周圍,如下所示:

r = re.compile('^(There|Did) (( |[A-Za-z])+) (today|yesterday)$')

但是現在,盡管它至少捕獲了中間組,但它還在m.groups()返回了一個額外的“e”字符,即:

('There', 'was a cat in the house', 'e', 'yesterday')

...雖然我覺得這與回溯有關,但我無法弄清楚它為什么會發生。 有人可以向我解釋為什么我得到這個結果,以及我如何能得到預期的結果?

您可以通過將中間捕獲組替換為中間捕獲組來簡化當前正則表達式並獲得正確的行為. (點)運算符將匹配任何字符,然后* (星號)運算符重復匹配任何字符:

import re

s1 = 'There was a cat in the house yesterday'
s2 = 'Did you see a cat in the house today'

x = re.compile("(There|Did)(.*)(today|yesterday)")
g1 = x.search(s1).groups()
g2 = x.search(s2).groups()

print(g1)
print(g2)

生成此輸出:

('那里','房子里有一只貓','昨天')
('做','你看到房子里有一只貓','今天')

重復捕獲組僅捕獲最后一次迭代。 如果您對數據不感興趣,請在重復組周圍放置捕獲組以捕獲所有迭代或使用非捕獲組。

來源https://regex101.com/

這是重新按預期工作:

^(There|Did) ([ A-Za-z]+) (today|yesterday)$
 r = re.compile('^(There|Did) (( |[A-Za-z])+) (today|yesterday)$')
                               ^ ^        ^

你有一些不必要的東西。 拿出那些並在你的中間組中包含空格:

r = re.compile('^(There|Did) ([A-Za-z ]+) (today|yesterday)$')
                                     ^ space

例:

>>> r = re.compile('^(There|Did) ([A-Za-z ]+) (today|yesterday)$')
>>> r.search('There was a a cat in the hosue yesterday').groups()
('There', 'was a a cat in the hosue', 'yesterday')

此外,如果您希望空格成為中間(第二)組的一部分,請取出捕獲組之間的空格

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM