如何检查字符串中的值是否为IP地址

Roh*_*hit 31 ruby string ip ruby-on-rails ipv6

当我这样做

ip = request.env["REMOTE_ADDR"]
Run Code Online (Sandbox Code Playgroud)

我得到了客户端的IP地址.但是如果我想验证变量中的值是否真的是IP呢?我怎么做?

请帮忙.提前致谢.抱歉,如果重复这个问题,我没有努力找到它......

编辑

那么IPv6 IP呢?

mol*_*olf 35

为什么不让图书馆为您验证呢?您不应该引入无法维护的复杂正则表达式.

% gem install ipaddress
Run Code Online (Sandbox Code Playgroud)

然后,在您的应用程序中

require "ipaddress"

IPAddress.valid? "192.128.0.12"
#=> true

IPAddress.valid? "192.128.0.260"
#=> false

# Validate IPv6 addresses without additional work.
IPAddress.valid? "ff02::1"
#=> true

IPAddress.valid? "ff02::ff::1"
#=> false


IPAddress.valid_ipv4? "192.128.0.12"
#=> true

IPAddress.valid_ipv6? "192.128.0.12"
#=> false
Run Code Online (Sandbox Code Playgroud)

您也可以使用Ruby的内置IPAddr类,但它不适合验证.

当然,如果应用程序服务器或框架为您提供了IP地址,则根本没有理由进行验证.只需使用提供给您的信息,并优雅地处理任何异常.


win*_*ire 35

Ruby已经在标准库中使用了所需的Regex.结账解析.

require "resolv"

"192.168.1.1"   =~ Resolv::IPv4::Regex ? true : false #=> true
"192.168.1.500" =~ Resolv::IPv4::Regex ? true : false #=> false

"ff02::1"    =~ Resolv::IPv6::Regex ? true : false #=> true
"ff02::1::1" =~ Resolv::IPv6::Regex ? true : false #=> false
Run Code Online (Sandbox Code Playgroud)

如果你喜欢它的短途...

require "resolv"

!!("192.168.1.1"   =~ Resolv::IPv4::Regex) #=> true
!!("192.168.1.500" =~ Resolv::IPv4::Regex) #=> false

!!("ff02::1"    =~ Resolv::IPv6::Regex) #=> true
!!("ff02::1::1" =~ Resolv::IPv6::Regex) #=> false
Run Code Online (Sandbox Code Playgroud)

玩得开心!

更新(2018-10-08):

从下面的评论我喜欢非常短的版本:

!!(ip_string =~ Regexp.union([Resolv::IPv4::Regex, Resolv::IPv6::Regex]))
Run Code Online (Sandbox Code Playgroud)

铁轨非常优雅(也是下面的答案):

validates :ip,
          :format => {
            :with => Regexp.union(Resolv::IPv4::Regex, Resolv::IPv6::Regex)
          }
Run Code Online (Sandbox Code Playgroud)

  • 进一步简化它`!!((ip_string = ~resolv :: IPv4 :: Regex)||(ip_string = ~Resolv :: IPv6 :: Regex))` (3认同)
  • 我更喜欢`!!(ip_string = ~Regexp.union([Resolv :: IPv4 :: Regex,Resolv :: IPv6 :: Regex])) (2认同)

Evg*_*nii 14

require 'ipaddr'
!(IPAddr.new(str) rescue nil).nil?
Run Code Online (Sandbox Code Playgroud)

我用它来快速检查,因为它使用内置库.支持ipv4和ipv6.它不是很严格,例如,它说"999.999.999.999"是有效的.如果您需要更高精度,请查看获奖答案.


小智 8

由于大多数答案都不涉及IPV6验证,我遇到了类似的问题.我使用Ruby Regex库解决了它,就像@wingfire提到的那样.

但我也使用正则表达式库来使用它的union方法中说明这里

我有这个代码进行验证:

validates :ip, :format => { 
                  :with => Regexp.union(Resolv::IPv4::Regex, Resolv::IPv6::Regex)
                }
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助别人!


小智 5

使用http://www.ruby-doc.org/stdlib-1.9.3/libdoc/ipaddr/rdoc/IPAddr.html它会为您执行验证。只需使用false挽救异常,您就知道它是无效的。

1.9.3p194 :002 > IPAddr.new('1.2.3.4')
 => #<IPAddr: IPv4:1.2.3.4/255.255.255.255> 
1.9.3p194 :003 > IPAddr.new('1.2.3.a')
ArgumentError: invalid address
  from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/ipaddr.rb:496:in `rescue in initialize'
  from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/ipaddr.rb:493:in `initialize'
  from (irb):3:in `new'
  from (irb):3
  from /usr/local/rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>'
Run Code Online (Sandbox Code Playgroud)


Kno*_*y66 5

require 'ipaddr'

def is_ip?(ip)
  !!IPAddr.new(ip) rescue false
end

is_ip?("192.168.0.1")
=> true

is_ip?("www.google.com")
=> false
Run Code Online (Sandbox Code Playgroud)

或者,如果您不介意扩展核心类:

require 'ipaddr'

class String
  def is_ip?
    !!IPAddr.new(self) rescue false
  end
end

"192.168.0.1".is_ip?
=> true

"192.168.0.512".is_ip?
=> false
Run Code Online (Sandbox Code Playgroud)