[英]python match only captures first and last group - am I misunderstanding something?
我正在研究一個與一系列作者匹配的Python腳本,我正在使用re
-module。 我遇到了意想不到的事情,我已經能夠將它簡化為以下非常簡單的例子:
>>> import re
>>> s = "$word1$, $word2$, $word3$, $word4$"
>>> word = r'\$(word\d)\$'
>>> m = re.match(word+'(?:, ' + word + r')*', s)
>>> m.groups()
('word1', 'word4')
所以我正在定義一個'基本'正則表達式,它匹配我輸入的主要部分,有一些可識別的功能(在這種情況下我使用$
-signs),而不是我嘗試匹配一個單詞加上可能的附加單詞列表。
我原以為m.groups()
會顯示:
>>> m.groups()
('word1', 'word2', 'word3', 'word4')
但顯然我做錯了什么。 我想知道為什么這個解決方案不起作用以及如何改變它,以便我得到我正在尋找的結果。 順便說一句,這是Linux機器上的Python 2.6.6,如果重要的話。
雖然您正在匹配每個$word#$
,但第二個捕獲組將不斷被匹配的最后一個項目替換。
我們來看看調試器:
>>> expr = r"\$(word\d)\$(?:, \$(word\d)\$)*"
>>> c = re.compile(expr, re.DEBUG)
literal 36
subpattern 1
literal 119
literal 111
literal 114
literal 100
in
category category_digit
literal 36
max_repeat 0 65535
subpattern None
literal 44
literal 32
literal 36
subpattern 2
literal 119
literal 111
literal 114
literal 100
in
category category_digit
literal 36
如您所見,只有2個捕獲組: subpattern 1
和subpattern 2
。 每次找到另一個$word#$
, subpattern 2
都會被覆蓋。
至於一個潛在的解決方案,我建議使用re.findall()
而不是re.match()
:
>>> s = "$word1$, $word2$, $word3$, $word4$"
>>> authors = re.findall(r"\$(\w+)\$", s)
>>> authors
['word1', 'word2', 'word3', 'word4']
正則表達式中只有兩個捕獲組。 嘗試re.findall(word, s)
代替。
regex
模塊支持重復捕獲。
如果您有可選或重復的捕獲組,則執行以下操作:
(?:, \$(word\d)\$)*
正則表達式只有一個地方用於返回在該組中捕獲的文本,盡管它匹配了字符串的3個部分,因此它包含最后一個這樣的子字符串。
要查找所有子字符串,可以在其他分隔符上使用findall
或tokenize字符串。
你可以像這樣避免正則表達式:
>>> s = "$word1$, $word2$, $word3$, $word4$"
>>> s.replace('$','').split()
['word1,', 'word2,', 'word3,', 'word4']
使用正則表達式,您可以使用findall()
代替:
>>> re.findall(word, s)
['word1', 'word2', 'word3', 'word4']
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.