簡體   English   中英

在 Python 中用正則表達式替換 '(' 時出錯

[英]Error in substituting '(' with regex in Python

嗨有以下字符串:

s = r'aaa (bbb (ccc)) ddd'

我想用{}查找並替換最里面的嵌套括號。 想要的輸出:

s = r'aaa (bbb {ccc}) ddd'

讓我們從嵌套的(開始。我使用以下正則表達式來查找嵌套括號,效果很好:

match = re.search(r'\([^\)]+(\()', s)
print(match.group(1))
(

然后我嘗試進行替換:

re.sub(match.group(1), r'\{', s)

但我收到以下錯誤:

error: missing ), unterminated subpattern at position 0

我真的不明白怎么了。

您可以使用

import re
s = r'aaa (bbb (ccc)) ddd'
print( re.sub(r'\(([^()]*)\)', r'{\1}', s) )
# => aaa (bbb {ccc}) ddd

請參閱Python 演示

詳情

  • \( - 一個(字符
  • ([^()]*) - 第 1 組( \1 ):除()之外的任何零個或多個字符
  • \) - a )字符。

替換是用花括號包裹的第 1 組值。

使用您展示的示例和嘗試,請嘗試使用 Python3.x 編寫和測試的以下 Python 代碼。 另外這里是代碼中使用的正則表達式的在線演示

import re
var = r'aaa (bbb (ccc)) ddd'
print( re.sub(r'(^.*?\([^(]*)\(([^)]*)\)(.*)', r'\1{\2}\3', var) )

所示樣本的輸出如下:

aaa (bbb {ccc}) ddd

Python代碼說明:

  • 在此處使用 python 的re庫進行正則表達式。
  • 創建一個名為var的變量,其中有值aaa (bbb (ccc)) ddd
  • 然后使用 python3 的print函數打印我們從re.sub函數獲得的值,該函數正在執行替換以獲得所需的輸出。

re.sub部分的解釋:基本上我們使用的是正則表達式(^.*?\([^(]*)\(([^)]*)\)(.*) (解釋如下),它創建了 3 個捕獲組(只是為了獲得所需的值),其中第一個捕獲組捕獲之前的值(它出現在ccc之前,第二個捕獲組中有ccc ,第三個捕獲組中有其余的值。在執行替換時,我們只是用它替換它\1{\2}\3並將值ccc包裝在{..}

正則表達式的解釋:

(^.*?\([^(]*)  ##Creating 1st capturing group which matches values from starting of value to till first occurrence of ( 
               ##with a Lazy match followed by a match which matches anything just before next occurrence of (
\(             ##Matching literal ( here, NO capturing group here as we DO NOT want this in output.
([^)]*)        ##Creating 2nd capturing group which has everything just before next occurrence of ) in it.
\)             ##Matching literal ) here, NO capturing group here as we DO NOT want this in output.
(.*)           ##Creating 3rd capturing group which has rest values in it.

你弄錯了參數順序:

子(模式,repl,字符串,計數=0,標志=0)

返回通過替換 repl 替換 string 中模式的最左側非重疊出現而獲得的字符串。 repl 可以是字符串或可調用對象; 如果是字符串,則處理其中的反斜杠轉義。 如果它是可調用的,它會傳遞 Match 對象,並且必須返回要使用的替換字符串。

模式首先出現,但是因為您已經給它match.group(1) ,所以它會將'('視為模式,其中包含不匹配和未轉義的括號。

我認為您所追求的是:

re.sub(r'\([^\)]+(\()', r'\1{', s)
'aaa ({ccc)) ddd'

正如您對我對該問題的評論的回復所示,以下示例字符串將按指示進行轉換:

'(aaa) (bbb (ccc)) ddd'                => '(aaa) (bbb {ccc}) ddd'
'(aaa (eee)) (bbb ccc) ddd'            => '(aaa {eee}) (bbb ccc) ddd'
'(aaa) (ee (ff (gg))) (bbb (ccc)) ddd' => '(aaa) (ee (ff {gg})) (bbb {ccc}) ddd'

我們無法使用單個正則表達式獲得這些結果,但我們可以通過執行一系列正則表達式來實現

r'\(([^()]*)\)(?=(?:[^()]*\)){n})'

對於n = 0, 1, ....並將匹配替換為

r'{\1}'

如果n = N是沒有匹配的n的最小值,則所需的替換由n = N-1生成的字符串給出。


我假設字符串有平衡括號

字符串'a(b X c)''a(b(c(d X e)f)g)'有平衡括號; 'a(b(c(d X e)fg)''a(b))cd X ((efg)'沒有。

字符串中任何字符的嵌套級別等於遇到左括號之前的右括號數(等效地,遇到右括號之前的左括號數)。 以下字符串中'X'的嵌套級別如下所示:

String          Nesting level
_____________________________
a X b                 0
a(b X c)              1
a(b(c X d)e)f         2
a(b(c(d X e)f)(g))    3

考慮字符串

'(aaa) (ee (ff (gg))) (bbb (ccc)) ddd'

我們首先設置n = 0以獲得

r'\(([^()]*)\)(?=(?:[^()]*\)){0})'

Demo 0顯示匹配的替換產生字符串

{aaa} (ee (ff {gg})) (bbb {ccc}) ddd

現在設置n = 1以生成正則表達式

\(([^()]*)\)(?=(?:[^()]*\)){1})

演示 1顯示匹配的替換產生字符串

(aaa) (ee (ff {gg})) (bbb {ccc}) ddd

接下來設置n = 2以生成正則表達式

\(([^()]*)\)(?=(?:[^()]*\)){2})

Demo 2Python demo顯示匹配的替換產生字符串

(aaa) (ee (ff {gg})) (bbb (ccc)) ddd

接下來設置n = 3以生成正則表達式

\(([^()]*)\)(?=(?:[^()]*\)){3})

演示 3顯示沒有匹配項。 因此,我們得出結論n = 2是嵌套括號的最大級別,因此所需的替換字符串必須是在n = 2時產生的字符串:

(aaa) (ee (ff {gg})) (bbb (ccc)) ddd

演示 4說明可能存在聯系。

暫無
暫無

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

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