Ruby正则表达式:全部扫描

时间:2010-10-24 13:13:11

标签: ruby regex

我有一个字符串:

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中执行此操作?

我试过了:

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

但它只返回[]中的第一个元素,并且不会使逗号可选(在“]”的末尾。)

4 个答案:

答案 0 :(得分:1)

你需要告诉正则表达式在每个元素之后不需要,,而是在除了第一个元素之外的每个参数之前。这导致以下正则表达式:

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"]]]

答案 1 :(得分:1)

这是另一种使用哈希来存储内容的方法,而不是正则表达式。

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]"]

答案 2 :(得分:0)

首先拆分群组

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"]]]

答案 3 :(得分:0)

如果我理解正确,你可能想得到这样的数组。

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

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