Как проверить, является ли значение в строке IP-адресом - PullRequest
29 голосов
/ 03 сентября 2010

когда я делаю это

ip = request.env["REMOTE_ADDR"]

Я получаю IP-адрес клиента. Но что, если я хочу проверить, действительно ли значение в переменной является IP? Как мне это сделать?

Пожалуйста, помогите. Заранее спасибо. И извините, если этот вопрос повторяется, я не стал его искать ...

EDIT

А как насчет IPv6 IP?

Ответы [ 12 ]

34 голосов
/ 03 сентября 2010

Почему бы не позволить библиотеке проверить ее для вас? Не следует вводить сложные регулярные выражения, которые невозможно поддерживать.

% 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-адрес предоставляется вам сервером приложений или платформой, нет никакой причины для проверки вообще. Просто используйте предоставленную вам информацию и изящно обработайте любые исключения.

32 голосов
/ 01 марта 2013

У Ruby уже есть необходимое регулярное выражение в стандартной библиотеке.Оформить заказ 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

Если вам нравится короткий путь ...

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

Получайте удовольствие!

Обновление (2018-10-08):

Из комментариев ниже я люблю очень короткую версию:

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

Очень элегантно с рельсами (также ответ снизу):

validates :ip,
          :format => {
            :with => Regexp.union(Resolv::IPv4::Regex, Resolv::IPv6::Regex)
          }
14 голосов
/ 20 июня 2012
require 'ipaddr'
!(IPAddr.new(str) rescue nil).nil?

Я использую его для быстрой проверки, потому что он использует встроенную библиотеку.Поддерживает ipv4 и ipv6.Это не очень строго, хотя, это говорит, что '999.999.999.999' допустим, например.Смотрите победный ответ, если вам нужно больше точности.

8 голосов
/ 07 марта 2016

Поскольку большинство ответов не говорят о проверке IPV6, у меня была похожая проблема. Я решил это с помощью библиотеки Ruby Regex, как упомянул @wingfire.

Но я также использовал библиотеку Regexp, чтобы использовать метод union, как объяснено здесь

У меня есть этот код для проверки:

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

Надеюсь, это кому-нибудь поможет!

5 голосов
/ 25 июля 2012

Используйте 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>'
4 голосов
/ 03 сентября 2010

Все ответы выше, начиная с IPv4 ... вы должны спросить себя, насколько разумно ограничивать ваше приложение IPv4, добавляя такие проверки в этот день, когда сеть мигрирует на IPv6.

Если вы спросите меня: не проверяйте это вообще. Вместо этого просто передайте строку как есть сетевым компонентам, которые будут использовать IP-адрес, и дайте им выполнить проверку. Поймайте исключения, которые они будут выдавать, когда это не так, и используйте эту информацию, чтобы сообщить пользователю, что произошло. Не изобретай колесо, опирайся на работу других.

3 голосов
/ 25 октября 2014
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
2 голосов
/ 18 апреля 2017

Попробуйте это

Использование IPAddr

require 'ipaddr'
true if IPAddr.new(ip) rescue false
1 голос
/ 03 сентября 2010

Это регулярное выражение, которое я использую, которое я нашел здесь

/^(?:(?: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 голосов
/ 28 ноября 2013

для сопоставления действительного 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}$

потому что многие движки регулярных выражений соответствуют первой возможности в последовательности ИЛИ

Вы можете попробовать свой движок регулярных выражений: 10.48.0.200

проверить разницу здесь

...