2016-12-08 256 views
0

我正在訪問一些舊的Python代碼,它們之前沒有拋出任何錯誤,但是當我嘗試運行它時,我遇到了一個錯誤。這是在給我一個錯誤代碼:Python正則表達式丟失括號錯誤

import re 

text = r"I quote \"How're you?\" to you." 
double = [z.start() for z in re.finditer('(?<!\\)(?:\\\\)*(")', text)] 
single = [z.start() for z in re.finditer("(?<!\\)(?:\\\\)*(')", text)] 
print(double) 
print(single) 

我曾希望從這項計劃中得到的輸出是:

[] 
[13] 

然而,這給我的錯誤:

double = [z.start() for z in re.finditer('(?<!(?:\\))(?:\\\\)*(")', text)] 
File "C:\Users\Me\AppData\Local\Programs\Python\Python35-32\lib\re.py", line 220, in finditer 
return _compile(pattern, flags).finditer(string) 
File "C:\Users\Me\AppData\Local\Programs\Python\Python35-32\lib\re.py", line 293, in _compile 
p = sre_compile.compile(pattern, flags) 
File "C:\Users\Me\AppData\Local\Programs\Python\Python35-32\lib\sre_compile.py", line 536, in compile 
p = sre_parse.parse(p, flags) 
File "C:\Users\Me\AppData\Local\Programs\Python\Python35-32\lib\sre_parse.py", line 829, in parse 
p = _parse_sub(source, pattern, 0) 
File "C:\Users\Me\AppData\Local\Programs\Python\Python35-32\lib\sre_parse.py", line 437, in _parse_sub 
itemsappend(_parse(source, state)) 
File "C:\Users\Me\AppData\Local\Programs\Python\Python35-32\lib\sre_parse.py", line 722, in _parse 
source.tell() - start) 
sre_constants.error: missing), unterminated subpattern at position 0 

值得一提的是,我在運行這個之前更新了python,所以也許python的更新導致了這個錯誤? (我現在正在運行Python 3.5.2,但我不記得以前是什麼)

此外,萬一它有幫助,我試圖找到所有情況下的單引號或雙引號沒有逃脫反斜線即

「和」拾取

\「和\」不

\」和\」拾取等等...

我打算用這然後將字符串中的嵌套字符串從字符串的其他部分分離出來

這是否定後視(? <!\\)這是造成這個問題,但我看不出有什麼問題。反斜槓由前面的那個逃脫,所以我看不到丟失的支架在哪裏。

奇怪的是,這適用於regex101,所以我開始用盡方法來調試這個。

我試圖爲負回顧後不同的替代,試圖得到這個工作:

(?<!\) #Gets the error, but that is expected 

(?<!\\\\) #Same error again, same problem as the original case 

(?<!\\\) #Returns [8, 20] and [13] 

顯然這最後一個有不正確的語法。然而,Python正在將其解釋爲正確的,但我不知道它實際上將其解釋爲什麼。

無論如何,我知道可能有一些簡單的解釋,也許一些RegEx語法我不知道。另外,如果有一種替代方案,對於我所嘗試的方法來說不那麼麻煩,請隨時給我提供該解決方案。

非常感謝你,我幾乎撕裂了我的頭髮,

EDW

+1

regex101會自動使它成爲原始字符串'r'...''。也許試試? –

回答

0

只需添加r的正則表達式字符串

import re 
text = r"I quote \"How're you?\" to you." 
double = [z.start() for z in re.finditer(r'(?<!\\)(?:\\\\)*(")', text)] 
single = [z.start() for z in re.finditer(r"(?<!\\)(?:\\\\)*(')", text)] 
print(double) 
print(single) 

輸出的面前:

[] 
[13] 
+0

要清楚的是,其原因是它禁用字符串文字的反斜槓轉義行爲,除非以下字符是用於開始字符串的引號字符。當你不這樣做時,你傳遞給'finditer'的內容包含文字字符'(?<!\)(?:\\)*(「)';然後將它解釋爲轉義(for正則表達式的目的)接下來的關閉paren_ _總是使用正則表達式的原始字符串; Python是「有用的」,只處理定義的轉義(''\ d''是len 2;''\\''是len 1),但它只是當你不期待逃生處理時,它會讓你更加困惑 – ShadowRanger

+0

哇......這比我想象的要簡單得多,至少我做到了「正確」,這只是python試圖成爲「有用的」。回覆並感謝ShadowRanger的解釋 – EdW

+0

@EdW:好的,Python在這裏正確地做着事情,問題是它在其他場景中錯誤地做了事情,比如允許'\ d','\ s'等。被解釋爲一個反斜槓後跟一個字母(因此它們到達正則表達式引擎並被正確解釋),而'\ b','\\'和其他一些字符,ASCII轉義以及r egex轉義,被解釋爲它們的轉義值。 Python將'\\'轉換爲'\'是正確的,只是它應該轉換_more_反斜槓轉義,以便人們始終如一地碰到這個問題,而不是一切工作,直到他們遇到異常。 – ShadowRanger