Regex to match a , and seperate

I am attempting to iterate through each host when there is a comma
between brackets, how can I add that capability within the regex match
as I am using a , to split hosts like server1.localhost.com,
server[2-5].localhost.com etc…

I.e., server[1,2].localhost.com

Here is the code:

    # split each host or host ranges defined
    nodes_split = nodes_field.split(/[,;\n\t ]+/)
    puts "DEBUG: #{nodes_split.inspect}"
    nodes_split.each do |n|
    m = n.match(/(.+)[\[\(\{](\d+)[\.-]+(\d+)[\]\)\}](.+)/)
      if m # regex match true - range used

m[2].to_i.upto(m[3].to_i) do |x| host = m[1] + x.to_s + m[4]
$all_nodes << host
end
else # regex match failed - range not used
$all_nodes << n
end
end

skolo pen wrote in post #1010321:

str =
“server[1,2].localhost.com,server[2-5].localhost.com,server1.localhost.com

addresses = str.scan(/
(
[^.]+
[.]
[^.]+
[.]
[^,]+
)
,?
/xms).flatten

puts addresses

–output:–
server[1,2].localhost.com
server[2-5].localhost.com
server1.localhost.com

And if there is a space after the comma that separates the addresses,
then using split() is trivial.

irb(main):007:0> str =
“server[1,2].localhost.com,server[2-5].localhost.com,server1.localhost.com
=>
“server[1,2].localhost.com,server[2-5].localhost.com,server1.localhost.com

irb(main):008:0> str.scan %r{(?:[^,[]]+|[[^]]*])+}
=> [“server[1,2].localhost.com”, “server[2-5].localhost.com”,
server1.localhost.com”]

Now, if you want to be safe against multiple nesting levels you can use
recursive matching:

irb(main):033:0> str =
“server[1,2].localhost.com,server[2-5[3-9]].localhost.com,server1.localhost.com
=>
“server[1,2].localhost.com,server[2-5[3-9]].localhost.com,server1.localhost.com

irb(main):034:0> str.scan( %r{ (? (?: [^,[]]+ | (? [ (?:
[^[]] | \g )* ] ) )+ ) }x ).map { $~[:name] }
=> [“server1.localhost.com”, “server1.localhost.com”,
server1.localhost.com”]

with a bit friendlier formatting

irb(main):046:0* str.scan(
irb(main):047:1* %r{
irb(main):048:1/ (?
irb(main):049:1/ (?:
irb(main):050:1/ [^,[]]+
irb(main):051:1/ | (? [ (?: [^[]]+ | \g )* ] )
irb(main):052:1/ )+
irb(main):053:1/ )
irb(main):054:1/ }x ).map { $~[:name] }
=> [“server1.localhost.com”, “server1.localhost.com”,
server1.localhost.com”]

or (basically the same regexp without the outer named group):

irb(main):035:0> str.scan %r{ (?: [^,[]]+ | (? [ (?: [^[]]+ |
\g )* ] ) )+ }x do puts $& end
server[1,2].localhost.com
server[2-5[3-9]].localhost.com
server1.localhost.com
=>
“server[1,2].localhost.com,server[2-5[3-9]].localhost.com,server1.localhost.com

SCNR :slight_smile:

Cheers

robert