Ruby regex: отсканировать все - PullRequest
       0

Ruby regex: отсканировать все

0 голосов
/ 24 октября 2010

У меня есть строка:

TFS[MAD,GRO,BCN],ALC[GRO,PMI,ZAZ,MAD,BCN],BCN[ALC,...]...

Я хочу преобразовать ее в список:

list = (
[0] => "TFS"
    [0] => "MAD"
    [1] => "GRO"
    [2] => "BCN"
[1] => "ALC"
    [0] => "GRO"
    [1] => "PMI"
    [2] => "ZAZ"
    [3] => "MAD"
    [4] => "BCN"
[2] => "BCN"
    [1] => "ALC"
    [2] => ...
[3] => ...
)

Как мне это сделать в Ruby?

Iпопробовал:

(([A-Z]{3})\[([A-Z]{3},+))

Но он возвращает только первый элемент в [] и не делает запятую необязательной (в конце "]").

Ответы [ 4 ]

1 голос
/ 24 октября 2010

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

string = "TFS[MAD,GRO,BCN],ALC[GRO,PMI,ZAZ,MAD,BCN],BCN[ALC]"
z=Hash.new([])
string.split(/][ \t]*,/).each do |x|
   o,p=x.split("[")
   z[o]=p.split(",")
end
z.each_pair{|x,y| print "#{x}:#{y}\n"}

выход

$ ruby test.rb
TFS:["MAD", "GRO", "BCN"]
ALC:["GRO", "PMI", "ZAZ", "MAD", "BCN"]
BCN:["ALC]"]
1 голос
/ 24 октября 2010

Вы должны указать регулярному выражению, что , не требуется после каждого элемента, а вместо каждого аргумента, кроме первого. Это приводит к следующему регулярному выражению:

str="TFS[MAD,GRO,BCN],ALC[GRO,PMI,ZAZ,MAD,BCN],BCN[ALC]"
str.scan(/[A-Z]{3}\[[A-Z]{3}(?:,[A-Z]{3})*\]/)
#=> ["TFS[MAD,GRO,BCN]", "ALC[GRO,PMI,ZAZ,MAD,BCN]", "BCN[ALC]"]

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

str.scan(/([A-Z]{3})\[([A-Z]{3}(?:,[A-Z]{3})*)\]/)
#=> [["TFS", "MAD,GRO,BCN"], ["ALC", "GRO,PMI,ZAZ,MAD,BCN"], ["BCN", "ALC"]]

Затем вы можете использовать map, чтобы разбить каждую часть внутри скобок на несколько токенов:

str.scan(/([A-Z]{3})\[([A-Z]{3}(?:,[A-Z]{3})*)\]/).map do |x,y|
  [x, y.split(",")]
end
#=> [["TFS", ["MAD", "GRO", "BCN"]],
#    ["ALC", ["GRO", "PMI", "ZAZ", "MAD", "BCN"]],
#    ["BCN", ["ALC"]]]
0 голосов
/ 24 октября 2010

Если я правильно понял, вы можете получить такой массив.

yourexamplestring.scan(/([A-Z]{3})\[([^\]]+)/).map{|a,b|[a,b.split(',')]}

[["TFS", ["MAD", "GRO", "BCN"]], ["ALC", ["GRO", "PMI", "ZAZ", "MAD", "BCN"]], ["BCN", ["ALC", "..."]]]
0 голосов
/ 24 октября 2010

сначала разбейте группы

groups = s.scan(/[^,][^\[]*\[[^\[]*\]/) 
# => ["TFS[MAD,GRO,BCN]", "ALC[GRO,PMI,ZAZ,MAD,BCN]"]

Теперь у вас есть группы, все остальное довольно просто:

groups.map {|x| [x[0..2], x[4..-2].split(',')] }
# => [["TFS", ["MAD", "GRO", "BCN"]], ["ALC", ["GRO", "PMI", "ZAZ", "MAD", "BCN"]]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...