2012-01-25 27 views
10

對於學校我應該編寫一個提取IP地址的Python RE腳本。我正在使用的正則表達式似乎與re.search()一起使用,但不與re.findall()一起使用。Python正則表達式 - re.search()vs re.findall()

exp = "(\d{1,3}\.){3}\d{1,3}" 
ip = "blah blah 192.168.0.185 blah blah" 
match = re.search(exp, ip) 
print match.group() 

的匹配,始終是192.168.0.185,但它的不同,當我做re.findall()

exp = "(\d{1,3}\.){3}\d{1,3}" 
ip = "blah blah 192.168.0.185 blah blah" 
matches = re.findall(exp, ip) 
print matches[0] 

0. 

我不知道爲什麼re.findall()收益率0時re.search()產生192.168.0.185,因爲我m對這兩個函數使用相同的表達式。

我該怎麼做才能讓re.findall()真的能正確地遵循這個表達式?或者我犯了一些錯誤?

回答

12

findall返回匹配的列表,並從文檔:

如果一個或多個基團存在於該圖案,返回組的 列表;如果模式 有多個組,這將是元組列表。

所以,以前的表達均匹配在最後一場比賽是0.

解決您的問題利用字符串中3次一組:exp = "(?:\d{1,3}\.){3}\d{1,3}";通過使用非分組版本,沒有返回的組,因此在兩種情況下均返回匹配。

+0

這很好,謝謝。 – user1168906

3

你只捕獲該正則表達式中的0,因爲它將是最後一個被捕獲的。

更改表達式捕獲整個IP和重複部分是一個非捕獲組:

In [2]: ip = "blah blah 192.168.0.185 blah blah" 

In [3]: exp = "((?:\d{1,3}\.){3}\d{1,3})" 

In [4]: m = re.findall(exp, ip) 

In [5]: m 
Out[5]: ['192.168.0.185'] 

In [6]: 

如果它有助於解釋的正則表達式:

In [6]: re.compile(exp, re.DEBUG) 
subpattern 1 
    max_repeat 3 3 
    subpattern None 
     max_repeat 1 3 
     in 
      category category_digit 
     literal 46 
    max_repeat 1 3 
    in 
     category category_digit 

這就解釋子模式。子模式1是findall捕獲的內容。