2012-01-25 8 views
10

私はIPアドレスを抽出するPythonのREスクリプトを書くつもりです。私が使用している正規表現はre.search()で動作するようですが、re.findall()では動作しません。 Python正規表現 - re.findall()対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を生み出します両方の関数で同じ式を使用しています。

これを行うにはどうすればいいですか?re.findall()は実際に正しく式に従いますか?あるいは私はある種の間違いをしていますか?

答えて

12

findallはマッチのリストを返し、ドキュメントから:

1つまたは複数のグループが、グループの リストを返し、パターン中に存在する場合。パターン に複数のグループがある場合、これはタプルのリストになります。

だから、あなたの前の式は最後のマッチがあなたの問題の使用を修正するには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によって捕捉されるものです。