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

2019-01-31 19:14发布

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?

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

12条回答
Juvenile、少年°
2楼-- · 2019-01-31 19:15

Ruby has already the needed Regex in the standard library. Checkout 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):

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)
          }
查看更多
forever°为你锁心
3楼-- · 2019-01-31 19:20

for match a valid IP adress with regexp use

^(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}$

instead of

^([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}$

because many regex engine match the first possibility in the OR sequence

you can try your regex engine : 10.48.0.200

test the difference here

查看更多
做个烂人
4楼-- · 2019-01-31 19:21

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.

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.

查看更多
\"骚年 ilove
5楼-- · 2019-01-31 19:25

Try this

Use IPAddr

require 'ipaddr'
true if IPAddr.new(ip) rescue false
查看更多
甜甜的少女心
6楼-- · 2019-01-31 19:27

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

查看更多
霸刀☆藐视天下
7楼-- · 2019-01-31 19:29

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

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>'
查看更多
登录 后发表回答