[英]Previous group match in Python regex
我嘗試捕獲看起來像%a
, %b
等的字符串片段,並用一些值替換它們。 此外,我希望能夠通過鍵入%%
來轉義%
字符。
在示例字符串中%d%%f%x%%%g
我想匹配%d %%f %x %% %g
( %d
, %x
, %g
)。
我的正則表達式如下所示:
(?:[^%]|^)(?:%%)*(%[a-z])
(?:[^%]|^)
- 匹配行的開頭或與%
不同的字符 (?:%%)*
- 匹配0次或更多次%%
(轉義%
) (%[az])
- 與%a
, %b
等模式正確匹配 添加前兩個元素以支持轉義%
字符。
但是,在示例字符串上運行regexp時,找不到最后一個片段( %g
):
>>> import re
>>> pat = re.compile("(?:[^%]|^)(?:%%)*(%[a-z])")
>>> pat.findall("%d%%f%x%%%g")
['%d', '%x']
但在%%%g
之前添加一個字符后,它開始正常工作:
>>> pat.findall("%d%%f%x %%%g")
['%d', '%x', '%g']
匹配到組(%[az])
后,看起來x
再次與[^%]
不匹配。 如何更改正則表達式以強制它再次檢查上一個匹配的最后一個字符? 我讀到了\\G
,但它沒有幫助。
為什么它沒有選擇%g
?
要選擇%g
,它必須具有%%
。 甚至在此之前它必須具有non-%
字符,或者在字符串的開頭。 所以, x%%%g
可以與你匹配。 但是在先前的匹配期間(即在打印%x
)選擇了該x
。
簡單來說,你的正則表達式匹配重疊。 所以你可以用下面的方法克服這一點。 我把你的正則表達式放在(?= ... )
pat = re.compile("(?=(?:[^%]|^)(?:%%)*(%[a-z]))")
你需要以不同的方式構建你的正則表達式:
>>> import re
>>> regex = re.compile(r"(?:[^%]|%%)*(%[a-z])")
>>> regex.findall("%d%%f%x%%%g")
['%d', '%x', '%g']
說明:
(?: # Start of a non-capturing group:
[^%] # Either match any character except %
| # or
%% # match an "escaped" %.
)* # Do this any number of times.
( # Match and capture in group 1:
%[a-z] # % followed by a lowercase ASCII alphanumeric
) # End of capturing group
在我看來,要趕上只有每部分%x
由偶數的前面%
。
如果是,則模式為"(?<!%)(?:%%)*(%[az])"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.