增加最后IPv4数字的更清洁方法

时间:2012-11-18 20:22:48

标签: ruby

这是我的IP:192.168.2.0

我需要得到一个像这样的数组:

["192.168.2.0",
 "192.168.2.1",
 "192.168.2.2",
 "192.168.2.3",
 "192.168.2.4",
 "192.168.2.5"]

以下是我如何将最后一位数字增加到5

ip = '192.168.2.0'

ips = 0.upto(5).map do |n|
  ip.sub(/\.\d+$/, '.' << n.to_s)
end

然而,它是狗慢,我讨厌它的样子。

重要 - 我需要保持原始ip不受影响,以便稍后通过ip变量引用它。

4 个答案:

答案 0 :(得分:4)

标准库有IPAddr,它支持succ方法。

require 'ipaddr'
ip = "192.168.2.0"

ips = [ip]
5.times do 
  ips << IPAddr.new(ips.last).succ.to_s
end
p ips
# =>["192.168.2.0", "192.168.2.1", "192.168.2.2", "192.168.2.3", "192.168.2.4", "192.168.2.5"]

#Ranges work:
ip_range = IPAddr.new("192.168.2.0")..IPAddr.new("192.168.2.5")
p ip_range.map(&:to_s)
# =>["192.168.2.0", "192.168.2.1", "192.168.2.2", "192.168.2.3", "192.168.2.4", "192.168.2.5"]

答案 1 :(得分:1)

只要您处理9下的数字,就可以使用succ(或next):

ip = '192.168.2.0'

p (0...5).inject([ip]) { |l| l << l.last.succ }

#=> ["192.168.2.0", "192.168.2.1", "192.168.2.2", "192.168.2.3", "192.168.2.4", "192.168.2.5"]

如果您需要增加至255,请使用split,这比正则表达式快得多:

p (0..255).inject([ip]) { |l, d| l << (l.last.split('.')[0..2] << d).join('.') }

#=> ["192.168.2.0" ... "192.168.2.255"]

请参阅live demo here

答案 2 :(得分:1)

试试这个,它使用split / join而不是regexes。

ip = '192.168.2.0'

ips = 0.upto(5).map do |n|
  ip.split('.').tap{|i| i[-1] = n }.join('.')
end

答案 3 :(得分:1)

我建议使用stdlib中的IPAddr,因为它会优雅地处理八位字节翻转(当你点击.255时),并且还有一些有用的子网划分功能等。

require 'ipaddr'
current = ip = IPAddr.new('192.168.2.0')
array = [ip]
until current.to_s == '192.168.2.5'
  array << current = current.succ
end
array.map!(&:to_s)