2010-10-24 61 views
0

我有一個字符串:紅寶石正則表達式:掃描所有

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},+)) 

但它在[]中只返回第一元件和不會使逗號可選的(在「]」的端部)。

回答

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

如果我理解正確的話,你可能會想這樣的陣列。

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

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

哎呀......我是個慢性子。 – Nakilon 2010-10-24 13:27:11

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