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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3634998/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 23:08:46  来源:igfitidea点击:

How do I check whether a value in a string is an IP address

ruby-on-railsrubystringipipv6

提问by Rohit

when I do this

当我这样做时

ip = request.env["REMOTE_ADDR"]

I get the client's IP address it it. But what if I want to validate whether the value in the variable is really an IP? How do I do that?

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

Please help. Thanks in advance. And sorry if this question is repeated, I didn't take the effort of finding it...

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

EDIT

编辑

What about IPv6 IP's??

IPv6 IP呢??

回答by wingfire

Ruby has already the needed Regex in the standard library. Checkout resolv.

Ruby 已经在标准库中提供了所需的 Regex。结帐RESOLV

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

If you like it the short way ...

如果你喜欢它的简短方式......

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

Have fun!

玩得开心!

Update (2018-10-08):

更新 (2018-10-08):

From the comments below i love the very short version:

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

!!(ip_string =~ Regexp.union([Resolv::IPv4::Regex, Resolv::IPv6::Regex]))

Very elegant with rails (also an answer from below):

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

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

回答by molf

Why not let a libraryvalidate it for you? You shouldn't introduce complex regular expressions that are impossible to maintain.

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

% gem install ipaddress

Then, in your application

然后,在您的应用程序中

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

You can also use Ruby's built-in IPAddrclass, but it doesn't lend itself very well for validation.

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

Of course, if the IP address is supplied to you by the application server or framework, there is no reason to validate at all. Simply use the information that is given to you, and handle any exceptions gracefully.

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

回答by Evgenii

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

I use it for quick check because it uses built in library. Supports both ipv4 and ipv6. It is not very strict though, it says '999.999.999.999' is valid, for example. See the winning answer if you need more precision.

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

回答by Philippe B.

As most of the answers don't speak about IPV6 validation, I had the similar problem. I solved it by using the Ruby Regex Library, as @wingfire mentionned it.

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

But I also used the Regexp Library to use it's unionmethod as explained here

但我也使用 Regexp 库来使用它的union方法,如解释here

I so have this code for a validation :

我有这个验证代码:

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

Hope this can help someone !

希望这可以帮助某人!

回答by mar

Use http://www.ruby-doc.org/stdlib-1.9.3/libdoc/ipaddr/rdoc/IPAddr.htmlit performs validation for you. Just rescue the exception with false and you know that it was invalid.

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

回答by Stijn de Witt

All answers above asume IPv4... you must ask yourself how wise it is to limit you app to IPv4 by adding these kind of checks in this day of the net migrating to IPv6.

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

If you ask me: Don't validate it at all. Instead just pass the string as-is to the network components that will be using the IP address and let them do the validation. Catch the exceptions they will throw when it is wrong and use that information to tell the user what happened. Don't re-invent the wheel, build upon the work of others.

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

回答by Knotty66

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

Or, if you don't mind extending core classes:

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

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

回答by Rahul Patel

Try this

尝试这个

Use IPAddr

IPAddr

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

回答by Gerhard

This regular expression I use which I found 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]?)$/

/^(?:(?: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]?)$/

回答by squadette

IP address in a string form must contain exactly four numbers, separated by dots. Each number must be in a range between 0 and 255, inclusive.

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