2013-04-11 122 views
4

我很新的python,所以我有一個字典中有一些鍵和字符串。如果在字典中找到字典中存在的模式,我必須替換字符串。字典和字符串都非常大。我正在使用正則表達式來查找模式。Python正則表達式錯誤:不平衡括號

這一切都正常工作,直到這樣的關鍵彈出「 - (」或本「( - )」。在這種情況下,蟒蛇給出了不平衡的括號內的錯誤

這裏是如何的代碼我寫的外觀:

somedict={'-(':'value1','(-)':'value2'} 
somedata='this is some data containing -(and (-)' 
for key in somedict.iterkeys(): 
    somedata=re.sub(key, 'newvalue', somedata) 

下面是我在控制檯中得到了錯誤

Traceback (most recent call last): 
    File "<console>", line 2, in <module> 
    File "C:\Python27\lib\re.py", line 151, in sub 
    return _compile(pattern, flags).sub(repl, string, count) 
    File "C:\Python27\lib\re.py", line 244, in _compile 
    raise error, v # invalid expression 
error: unbalanced parenthesis 

我也嘗試使用正則表達式編譯器將其許多方面並搜查了很多,但沒有發現什麼解決問題。任何幫助表示讚賞。

回答

7

您需要逃生使用re.escape()關鍵:

somedata = re.sub(re.escape(key), 'newvalue', somedata) 

否則內容將被解釋爲正則表達式。

您沒有使用正則表達式都在這裏,所以你可能也只是使用:

somedata = somedata.replace(key, 'newvalue') 

如果你想更換身邊只有整個單詞(所以用空格或標點符號市場上贏得,在輸入字符串的開始或結束),您需要某種邊界錨點,此時使用正則表達式是有意義的。如果你已經是字母數字字(加下劃線),\b會工作:

somedata = re.sub(r'\b{}\b'.format(re.escape(key)), 'newvalue', somedata) 

這使\b之前,你想替換字符串後,使bazfoo baz bar改變,但foo bazbaz bar

對於輸入涉及非字母數字「字」,你需要配合查找aheads空格或啓動和空格或端錨和查找屁股:

somedata = re.sub(r'(?:^|(?<=\s)){}(?:$|(?=\s))'.format(re.escape(key)), 'newvalue', somedata) 

這裏模式(?:^|(?<=\s))使用兩個錨點,字符串起始錨點和後退斷言,以匹配字符串開頭或空格緊鄰左側的位置。同樣,(?:$|(?=\s)對另一端也是如此,匹配字符串的末尾或位置後跟一個空格。

+0

非常感謝Martijn,它確實有效。然而,它也取代了子字符串,如果someData =' - ( - ('轉換爲'newvaluenewvalue'我怎麼能避免它。我只希望它被替換時,整個字符串匹配。即somedata應該保持不變,如果它不' 「 – 2013-04-11 11:24:41

+0

然後只是測試平等嗎?'如果somedata == key:somedata ='newvalue''也做你剛剛描述的。 – 2013-04-11 11:28:04

+0

如果'somedata ='這是somedata''並且關鍵是'is '這似乎並沒有在那裏工作'somedata.replace'也取代了子串,所以它似乎也不工作 – 2013-04-11 11:41:46

1

不要使用re的東西這麼簡單 - 只需更換:

somedata = somedata.replace(key, 'newvalue') 

這就是說,如果你從什麼構造的正則表達式,使用re.escape逃避特殊字符:

somedata=re.sub(re.escape(key), 'newvalue', somedata) 
+0

非常感謝你Pavel!有用!!但也取代了' - ( - ('轉換爲'newvaluenewvalue'),我怎麼能避免它,我只希望它被替換時,整個字符串匹配 – 2013-04-11 11:21:51

+0

你需要明確你的意思是什麼「whole string」。 - ('不完全是一個「word」 – 2013-04-11 11:24:01

+0

我的意思是說,正則表達式不應該替換一個子字符串是否匹配,比如這裏有一個例子:'data ='thisdog has a dog''和'data = re.sub(re.escape('dog'),'cat',data)'then'data ='thiscat has a cat',這不應該發生,結果應該是'data ='這個狗有一隻貓'。我想只在整個字符串不僅僅匹配它的一部分時才替換它。 – 2013-04-11 11:33:09