Получить IPv4 из строки Ruby, которая содержит как IPv4, так и IPv6? - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть строка из заголовка X-Forwarded-For, которая содержит адреса IPv4 и IPv6.

Мне нужно извлечь из строки только IPv4-адрес.

Он разделен запятыми, но их порядок меняется, поэтому я не могу просто разделить и вытащить второй элемент.

Пример: header = 2600:1740:8540:cff9:1c50:617:c9c5:63f7, 165.154.107.112

В конечном итоге я просто хочу 165.154.107.112.

Я использую Ruby 2.5.1 (и это, оказывается, внутри приложения Rails 5.2.0, для чего оно стоит) .

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Предполагая, что ваш заголовок всегда такой, как вы отправили:

require 'ipaddr'

header = "165.154.107.112, 2600:1740:8540:cff9:1c50:617:c9c5:63f7"

ip = header.split(', ').select {|ip| ip if IPAddr.new(ip).ipv4? }.pop

# => "165.154.107.112"
0 голосов
/ 12 сентября 2018
header = "2600:1740:8540:cff9:1c50:617:c9c5:63f7, 165.154.107.112, 166.155.108.113"

header.split(/\s?,\s?/).find { |s| IPAddr.new(s).ipv4? }
  #=> "165.154.107.112"

или

header.split(/,\s+/).select { |s| IPAddr.new(s).ipv4? }
  #=> ["165.154.107.112", "166.155.108.113"]

См. IPAddr :: new и IPAddr # ipv4? .

Если "header = " равночасть строки str, замените header.split на str[/\d.+/].split.

Если строка может содержать текст, который не является допустимым IP-адресом, вы можете написать следующее.

header.split(/\s?,\s?/).find { |s| (IPAddr.new(s) rescue nil)&.ipv4? }

IPAddr.new('cat'), например, поднимает исключение IPAddr::InvalidAddressError (invalid address).& - оператор безопасной навигации Ruby , дебютировавший в v2.3.

...