2016-12-29 3 views
1

Rubyでは、どのようにCSVファイルを解析して情報を出力できますか?たとえば:特定のIPアドレスのCSVファイルの解析

require 'csv' 

class CountryFilter 

    class << self 

    def find_specs_by_ip_address(ip) 
     CSV.foreach('GeoIPCountry.csv') do |row| 
     if row =~ Regexp.union(ip) 
      data = row.split(',') 
      return data[5] 
     else 
      return 'Unable to find country specifications' 
     end 
     end 
    end 

    end 

end 

puts CountryFilter.find_specs_by_ip_address('72.247.167.255') 

CSVファイル:

... 
"72.247.88.0","72.247.89.255","1224169472","1224169983","US","United States" 
"72.247.90.0","72.247.103.255","1224169984","1224173567","NL","Netherlands" 
"72.247.104.0","72.247.144.255","1224173568","1224184063","US","United States" 
"72.247.145.0","72.247.145.255","1224184064","1224184319","NL","Netherlands" 
"72.247.146.0","72.247.167.255","1224184320","1224189951","US","United States" 
"72.247.168.0","72.247.179.255","1224189952","1224193023","NL","Netherlands" 
"72.247.180.0","72.247.181.255","1224193024","1224193535","US","United States" 
"72.247.182.0","72.247.182.255","1224193536","1224193791","NL","Netherlands" 
"72.247.183.0","72.247.183.255","1224193792","1224194047","US","United States" 
... 

にはどうすればIPアドレスおよび出力のため、このCSVファイル、それが由来する国を解析することができますか?

+1

最初の2つの列は実際にはIP範囲を表していると思います。 – Felix

答えて

1

ノート

  • rowあなたが何かを分割し、dataを定義する必要はありません、すでに複数のセルを持つCSVの行です。
  • あなたのメソッドは、IPが見つかったかどうかの両方の場合に、最初の行の後に戻ります。
  • IPが見つからない場合にnilを返すことは、おそらく文字列を返すよりも良い考えです。コード
    require 'csv' 
    class CountryFilter 
        class << self 
        def find_specs_by_ip_address(ip) 
         CSV.foreach('GeoIPCountry.csv') do |row| 
         return row.last if row.first(2).include?(ip) 
         end 
        end 
        end 
    end 
    
    CountryFilter.find_specs_by_ip_address('72.247.167.255') 
    #=> "United States 
    CountryFilter.find_specs_by_ip_address('1.2.3.4') 
    #=> nil 
    

    V2

    リファクタリング

洞察に満ちたコメントの@Felixに感謝します。

この方法は、現在ip場合、IP範囲の境界、及びチェックことがIP1とIP2を考慮し、この範囲内である:

require 'csv' 
require 'ipaddr' 

module IPFilter 
    def self.find_country_by_ip_address(ip) 
    ip = IPAddr.new(ip).to_i 
    CSV.foreach('GeoIPCountry.csv') do |_, _, ip1, ip2, _, country_name| 
     return country_name if (ip1.to_i..ip2.to_i).cover?(ip) 
    end 
    end 
end 

p IPFilter.find_country_by_ip_address('72.247.167.123') 
#=> "United States" 
p IPFilter.find_country_by_ip_address('1.2.3.4') 
#=> nil 

Range#cover?

戻り真objが間にある場合範囲の始めと終わり。

+0

awh、それはそれを説明する! – User9123

+0

ありがとうございます。nilのIPに近いものを見つける方法がありますか?たとえば、127.0.0.1が見つからないとすれば、127.0.0.1などと最も近いものを見つけることができます。 – User9123

+1

構造が現在のものと異なるため、別の質問を書いてください –

0

は、この作業を行う方法

... 
CSV.foreach('GeoIPCountry.csv') do |a, b, c, d, e, country| 
    return country if a == ip || b == ip 
end 
... 

、これを試してみてください?

  • row

    は、すでにあなたは最高のa, b, c, d, eより意味のある名前を与えるマジックナンバー

NB、を避けるために、ブロックパラメータで行を展開することができコンマ

  • によって分割されます。

  • 関連する問題