2014-01-31 328 views
2

我有以下Python代碼會試圖讀取輸入文件並找到給正則表達式的下列情況:正則表達式的Python

[fF][eE][bB]([1-2][0-9]|[0-9] 

我寫了下面的Python代碼

#!/usr/bin/python 
import re 
import sys 

textFile = open(sys.argv[1], 'r') 
fileText = textFile.read() 
textFile.close() 
matches = re.findall("[fF][eE][bB] ([1-2][0-9]|[0-9])",fileText) 
print matches 

和我的輸入文件是:

1 2 3 the 
the quick 2354 
feb 1 
feb 0 
feb -10 
feb23 
feb 29 
feb 3 
february 10 

然而,當我跑我的代碼我獲得以下輸出:['1','29', '3']

我希望我的輸出更像['feb 1', 'feb 29', 'feb 3']

我真的不知道我在做什麼錯。任何幫助將不勝感激。

回答

1

爲了使matches包含匹配的文本,您需要在整個表達式周圍使用小括號。每對父親會有一個比賽組;您可以使用(feb (?:[12][0-9]|[1-9]))進行分組而不捕獲第二組。

但是,考慮到您的例子,或許您實際上想要在匹配時打印整個輸入行?

+0

還應注意'1-9'避免匹配'二月文本0' 。如果你想匹配,表達式可以簡化爲'(feb [12]?[0-9])'。 – tripleee

+0

是的,'re.IGNORECASE'也是。 – tripleee

1

如果你想打印這個樣子,

['feb 1', 'feb 29', 'feb 3'] 

您可以使用下面的代碼,

matches = re.findall("(feb (?:[12][0-9]|[1-9]))",fileText) 
    print matches 
3

你應該read the documentation。當表達式中存在時,re.findall只返回捕獲組。您應該簡單地從你的正則表達式中刪除捕獲組:

matches = re.findall("[fF][eE][bB] (?:[1-2][0-9]|[0-9])",fileText) 
            ^^ 

這就是說,這個正則表達式也將匹配feb 0,所以你可能需要使用

[fF][eE][bB] (?:[1-2][0-9]|[1-9]) 
          ^

相反。

現在,如果您使用re.IGNORECASE(使正則表達式匹配大寫和小寫字符)以及如果使用循環讀取文件內容(對於大文件更有效),則可以縮短正則表達式的時間。此外,這是一個很好的做法,原料您正則表達式模式:

with open(sys.argv[1], 'r') as textFile: 
    for line in textFile: 
     matches = re.match(r"feb (?:[1-2][0-9]|[1-9])", line, re.IGNORECASE) 
     if matches: 
      print matches.group() 

和當然,你可以把比賽中的列表太多,如果你需要在最後一個列表。

+0

+1真棒帖子,它包含了很多信息,其中大部分已經被我知道,但超過預期的信息未知。謝謝! – PascalVKooten

+0

@PascalvKooten不客氣:) – Jerry

0

如何:

(feb\s[1-9][0-9]?) 

相配:二月後跟一個空格和0到9之間1和9,然後任何其它任選的數字之間的一個數字。

嘗試:

matches = re.findall(r'(feb\s[1-9][0-9]?)',fileText) 
print matches 
>>> ['feb 1', 'feb 29', 'feb 3'] 

警告:這解決不了像 「二月51」

See it in action