簡體   English   中英

如何替換所有出現的正則表達式,就像重復應用替換一樣

[英]How to replace all occurrences of regex as if applying replace repeatedly

例如,我有很多產品尺寸的文本,如“2x4”,我想將其轉換為“2 xby 4”。

pattern = r"([0-9])\s*[xX\*]\s*([0-9])"

re.sub(pattern, r"\1 xby \2", "2x4")
'2 xby 4' # good

re.sub(pattern, r"\1 xby \2", "2x4x12")
'2 xby 4x12' # not good. need this to be '2 xby 4 xby 12'

描述我想要做的事情的一種方法是重復替換,直到不能再進行替換。 例如,我可以簡單地對上面的替換進行兩次以獲得我想要的東西

x = re.sub(pattern, r"\1 xby \2", "2x4x12")
x = re.sub(pattern, r"\1 xby \2", x)
'2 xby 4 xby 12'

但我認為有更好的方法

您可以使用此前瞻性正則表達式進行搜索:

r'([0-9]+)\s*[xX*]\s*(?=[0-9]+)'

(?=[0-9]+)是正向前瞻,只是通過向前看來斷言第二個數字的存在,但是不通過匹配數字來移動內部正則表達式指針。

並使用此替換:

r'\1 xby '

RegEx演示

碼:

>>> pattern = r'([0-9]+)\s*[xX*]\s*(?=[0-9]+)'

>>> re.sub(pattern, r'\1 xby ', "2x4")
'2 xby 4'

>>> re.sub(pattern, r'\1 xby ', "2x4x12")
'2 xby 4 xby 12'

我認為你可以通過一次通過來解決這個問題。 你真正想要做的是用xby替換x - 所以你可以掃描整個字符串一次,如果你不消耗數字的右邊。

為此,我建議使用前瞻性斷言。 基本上,確認您要替換的東西后跟數字,但不要吃過程中的數字。 這種表示法是(?= ...) - 請參閱re docpage

對我來說,我有以下內容 - 請注意,編譯正則表達式是可選的,\\ d通常優先於[0-9]:

pattern = re.compile(r"(\d+)\s*[xX\*]\s*(?=\d)")
pattern.sub(r"\1 xby ", "2x4x12")

'2 xby 4 xby 12'

在一次傳遞中,它將處理整個字符串。

因為你試圖重新運行已經由正則表達式轉換的文本的匹配,所以沒有更好的方法。

這有點像解開數學問題,如果你想這樣做:(2 + 3)+ 4,你需要替換“(2 + 3)”以便能夠替換“5 + 4”,因為字符串“你的原文中沒有5“。

您可能想要做的是測試您的字符串是否有任何匹配,並繼續在之前的結果上重新運行替換,直到找不到更多匹配項。

編輯:你也可以為它重復的次數制作幾個正則表達式,並按長度的降序運行它們。 即尋找2x3x5x2然后2x3x5然后2x3,因為逐步你不會擊中任何已被替換的東西。

暫無
暫無

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

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