![](/img/trans.png)
[英]Regex and python: substituting $$ with \[ and \] in a TeX document
[英]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代碼說明:
re
庫進行正則表達式。var
的變量,其中有值aaa (bbb (ccc)) ddd
。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 2和Python 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.