簡體   English   中英

Python正則表達式模塊與重新模塊 - 模式不匹配

[英]Python regex module vs re module - pattern mismatch

更新 :此問題已由提交者在be893e9中解決

如果遇到同樣的問題,請更新regex模塊。
您需要2017.04.23或更高版本。


正如在這個答案中指出的,我需要這個正則表達式

(?i)\b((\w{1,3})(-|\.{2,10})[\t ]?)+(\2\w{2,})

正在使用regex模塊...

import re     # standard library
import regex  # https://pypi.python.org/pypi/regex/

content = '"Erm....yes. T..T...Thank you for that."'
pattern = r"(?i)\b((\w{1,3})(-|\.{2,10})[\t ]?)+(\2\w{2,})"
substitute = r"\2-\4"

print(re.sub(pattern, substitute, content))
print(regex.sub(pattern, substitute, content))

輸出:

"Erm....yes. T-Thank you for that."
"-yes. T..T...Thank you for that."

問:如何我都要寫這個正則表達式來使regex模塊反應,因此用同樣的方法re模塊呢?

使用re模塊不是一個選項,因為我需要具有動態長度的后視鏡。

澄清一下如果正則表達式適用於兩個模塊會很好,但最后我只需要它用於regex

看來這個bug與回溯有關。 它在重復捕獲組時發生,並且捕獲組匹配但組之后的模式不匹配。

一個例子:

>>> regex.sub(r'(?:(\d{1,3})x)+', r'\1', '123x5')
'5'

作為參考,預期輸出將是:

>>> re.sub(r'(?:(\d{1,3})x)+', r'\1', '123x5')
'1235'

在第一次迭代中,捕獲組(\\d{1,3})消耗前3位數, x消耗以下“x”字符。 然后,由於+ ,第二次嘗試匹配。 這次, (\\d{1,3})匹配“5”,但x無法匹配。 但是,捕獲組的值現在(重新)設置為空字符串而不是預期的123

作為解決方法,我們可以阻止捕獲組進行匹配。 在這種情況下,將其更改為(\\d{2,3})足以繞過該錯誤(因為它不再匹配“5”):

>>> regex.sub(r'(?:(\d{2,3})x)+', r'\1', '123x5')
'1235'

至於有問題的模式,我們可以使用先行斷言; 我們將(\\w{1,3})更改為(?=\\w{1,3}(?:-|\\.\\.))(\\w{1,3})

>>> pattern= r"(?i)\b((?=\w{1,3}(?:-|\.\.))(\w{1,3})(-|\.{2,10})[\t ]?)+(\2\w{2,})"
>>> regex.sub(pattern, substitute, content)
'"Erm....yes. T-Thank you for that."'

編輯 :現在在正則表達式2017.04.23中解決了該錯誤

剛剛在Python 3.6.1中測試過,原始模式在reregex工作方式相同


原始解決方法 - 您可以使用惰性運算符+? (即一個不同的正則表達式,其行為與原始模式不同,例如T...Tha....Thank ):

pattern = r"(?i)\b((\w{1,3})(-|\.{2,10})[\t ]?)+?(\2\w{2,})"


2017.04.05中的錯誤是由於回溯,如下所示:

不成功的較長匹配會創建空的\\2組,從概念上講,它應該觸發回溯到較短的匹配,其中嵌套組不為空,但regex似乎“優化”並且不從頭開始計算較短的匹配,但使用一些緩存值,忘記撤消嵌套匹配組的更新。

貪婪匹配示例((\\w{1,3})(\\.{2,10})){1,3}將首先嘗試3次重復,然后回溯到更少:

expected: 1,3 [('Erm....', 'Erm', '....'), ('T...', 'T', '...')]
actual:   1,3 [('Erm....', '', '....'), ('T...', '', '...')]
expected: 3 []
actual:   3 []
expected: 2 [('T...', 'T', '...')]
actual:   2 [('T...', 'T', '...')]
expected: 1 [('Erm....', 'Erm', '....'), ('T..', 'T', '..'), ('T...', 'T', '...')]
actual:   1 [('Erm....', 'Erm', '....'), ('T..', 'T', '..'), ('T...', 'T', '...')]

輸出:

 expected: 1,3 [('Erm....', 'Erm', '....'), ('T...', 'T', '...')] actual: 1,3 [('Erm....', '', '....'), ('T...', '', '...')] expected: 3 [] actual: 3 [] expected: 2 [('T...', 'T', '...')] actual: 2 [('T...', 'T', '...')] expected: 1 [('Erm....', 'Erm', '....'), ('T..', 'T', '..'), ('T...', 'T', '...')] actual: 1 [('Erm....', 'Erm', '....'), ('T..', 'T', '..'), ('T...', 'T', '...')] 

暫無
暫無

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

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