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

问题描述 投票:0回答:13

当我这样做时

ip = request.env["REMOTE_ADDR"]

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

请帮忙。 提前致谢。抱歉,如果这个问题重复出现,我没有花功夫找到它......

编辑

IPv6 IP 怎么样?

ruby-on-rails ruby string ip ipv6
13个回答
53
投票

Ruby 已经在标准库中提供了所需的正则表达式。 结帐解决

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

如果你喜欢它的捷径...

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

玩得开心!

更新

从下面的评论中,我喜欢用于检查 IPv4 或 IPv6 的非常简短的版本:

!!(ip_string =~ Resolv::AddressRegex)

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

validates :ip,
          :format => {
            :with => Resolv::AddressRegex
          }

44
投票

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

% gem install ipaddress

然后,在您的应用程序中

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

您还可以使用 Ruby 的内置

IPAddr
类,但它不太适合验证。

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


15
投票
require 'ipaddr'
!(IPAddr.new(str) rescue nil).nil?

我用它来快速检查,因为它使用内置库。同时支持 ipv4 和 ipv6。但它不是很严格,例如,它说“999.999.999.999”是有效的。如果您需要更精确,请参阅获胜答案。


11
投票

由于大多数答案都没有谈到 IPV6 验证,所以我也遇到了类似的问题。 我通过使用 Ruby Regex 库解决了这个问题,正如 @wingfire 提到的那样。

但是我也使用正则表达式库来使用它的

union
方法,如here

所解释的那样

我有这个验证代码:

validates :ip, :format => { 
                  :with => Regexp.union(Resolv::IPv4::Regex, Resolv::IPv6::Regex)
                }

希望这可以帮助别人!


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>'

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

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

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

4
投票

以上所有答案都假设 IPv4...您必须问自己,在网络迁移到 IPv6 的今天,通过添加此类检查将您的应用程序限制为 IPv4 是多么明智。

如果你问我:根本不要验证它。相反,只需将字符串按原样传递给将使用 IP 地址的网络组件,并让它们进行验证。捕获错误时抛出的异常,并使用该信息告诉用户发生了什么。不要重新发明轮子,要在别人的工作基础上进行构建。


3
投票

试试这个

使用

IPAddr

require 'ipaddr'
true if IPAddr.new(ip) rescue false

2
投票

我使用的这个正则表达式是我在here

找到的

/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/


0
投票

字符串形式的IP地址必须恰好包含四个数字,以点分隔。每个数字必须在 0 到 255 之间(含 0 和 255)。


0
投票

使用正则表达式验证:

\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}

0
投票

使用正则表达式匹配有效的 IP 地址

^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$

而不是

^([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\.([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])){3}$

因为许多正则表达式引擎匹配 OR 序列中的第一个可能性

你可以尝试你的正则表达式引擎:10.48.0.200

测试差异在这里


0
投票

对于ipv4

def ipv4?(str)
   nums = str.split('.')
   reg = /^\d$|^[1-9]\d$|^1\d\d$|^2[0-4]\d$|^25[0-5]$/
   nums.length == 4 && (nums.count {|n| reg.match?(n)}) == 4
end
© www.soinside.com 2019 - 2024. All rights reserved.