2015-02-10 65 views
1

我在http://regexpal.com/上測試了以下代碼,它正確匹配我想要的字符串。我想找到它發生在中間的空間的4塊16個數字,所以我寫了下面的正則表達式:Python:意外的{n}匹配的正則表達式行爲

\d{4}(\s\d{4}){3} 

即匹配4個數字,然後匹配一個空格,接着三個四個重複組數字。在regexpal,這正確匹配:

test1234消息

在Python,不過,我運行下面的代碼:

>>> import re 
>>> p = re.compile('\d{4}(\s\d{4}){3}') 
>>> p.findall('test1234 message1234 5678 1234 5678') 
[' 5678'] 
>>> 

我不明白爲什麼它匹配'5678'的第二個實例,以及爲什麼它不符合我所期望的數字塊。

回答

3

原始字符串是定義正則表達式的推薦方式,但這裏的問題主要是因爲實施了findall方法。您需要將捕獲組存在於您的正則表達式中,以未捕獲組。因爲re.findall函數給出了第一個首選項來捕獲然後匹配。您的正則表達式\d{4}(\s\d{4}){3}與16位數字相匹配,但僅捕獲最後四位加上前面的空格。

p = re.compile(r'\d{4}(?:\s\d{4}){3}') 

例子:

>>> import re 
>>> p = re.compile(r'\d{4}(\s\d{4}){3}') 
>>> p.findall('test1234 message1234 5678 1234 5678') 
[' 5678'] 
>>> p = re.compile(r'\d{4}(?:\s\d{4}){3}') 
>>> p.findall('test1234 message1234 5678 1234 5678') 
['1234 5678 1234 5678'] 
+0

我認爲你應該提到原始字符串是推薦寫正則表達式的方法,但是在這種情況下,問題來自於執行'findall',如果在正則表達式中有任何切換,它將使用捕獲組中的內容。 – nhahtdh 2015-02-10 07:28:57

+0

謝謝...更新.. – 2015-02-10 07:37:02

-1

您需要可以與r前綴您的字符串或逃避你的反斜線:

p = re.compile(r'\d{4}(\s\d{4}){3}') 

p = re.compile('\\d{4}(\\s\\d{4}){3}') 
+1

原始字符串不是這裏的問題,雖然它是建議的做法。 Python爲無法識別的轉義序列保留''''''。 – nhahtdh 2015-02-10 07:27:20