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
How do I check whether a value in a string is an IP address
提问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 Gerhard
回答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)的范围内。

