2014-12-07 74 views
4

我有一個字符串"Animals (Reptiles Birds (Eagles Pigeons Crows))",我需要返回:將字符串轉換和括號來樹,紅寶石

a = [ 
    { 
    "Animals" => [ 
     { 
     "Reptiles" => nil 
     }, 
     { 
     "Birds" => [ 
      { "Eagles" => nil }, 
      { "Pigeons" => nil }, 
      { "Crows" => nil } 
     ] 
     } 
    ] 
    } 
] 

我不明白我怎麼能做到這一點。 我在哪裏可以找到一些例子或我可以在谷歌搜索?

+1

奇怪,奇怪的肯定,有趣! – 2014-12-07 00:23:53

+0

這看起來像是一個用於json解析練習的s表達式。我還沒有找到基於ruby的解決方案。 – vsnyc 2014-12-07 00:59:45

+0

聽起來像功課。 – 2014-12-07 07:11:52

回答

1

這裏有一種方法可以將字符串轉換爲數組。

代碼

def arrayify(arr) 
    a = split_arr(arr) 
    a.map do |h| 
    k = h.keys.first 
    v = h.values.first 
    case v 
    when Array then { k => arrayify(v) } 
    else { k=>v } 
    end 
    end 
end 

def split_arr(arr) 
    a = [] 
    while arr.any? 
    word = arr.shift 
    if arr.empty? || arr.first != ?(
     a << { word=>nil } 
    else 
     arr.shift 
     close_count = 0 
     b = [] 
     loop do 
     token = arr.shift 
     case token 
     when ?) 
      break if close_count == 0 
      close_count -= 1 
     when ?(then close_count += 1 
     end 
     b << token 
     end 
     a << { word=>b } 
    end 
    end 
    a 
end 

str = "Animals (Reptiles Birds (Eagles Pigeons Crows)) Foods (" + 
     "Snacks Breakfast (Pancakes Waffles))" 

arrayify(str.split) 

    #=> [{"Animals"=>[{"Reptiles" =>nil}, 
    #     {"Birds" =>[{"Eagles" =>nil}, 
    #        {"Pigeons"=>nil}, 
    #        {"Crows" =>nil} 
    #        ] 
    #     } 
    #    ] 
    # }, 
    # {"Foods" =>[{"Snacks" =>nil}, 
    #     {"Breakfast"=>[{"Pancakes"=>nil}, 
    #        {"Waffles" =>nil} 
    #        ] 
    #     } 
    #    ] 
    # } 
    # ] 
+0

非常感謝! – rel1x 2014-12-08 05:47:50

1

我不明白我該怎麼做。在哪裏可以找到一些示例或我可以在Google中搜索的內容?

使用遞歸正則表達式是一種選擇,特別是如果括號是適當的平衡:

http://www.regular-expressions.info/recurse.html

如果它在你的頭上,通過使用正則表達式正常的字符串遞歸犁。匹配類似:

[a-z]+ ?([^()]*) 

...然後用原始字符串中的佔位符替換匹配項。沖洗,重複。

使用解析器是另一種選擇。你可以寫一個簡單的一個,或使用工具例如爲:

http://thingsaaronmade.com/blog/a-quick-intro-to-writing-a-parser-using-treetop.html

1

這適用於你的榜樣,但我不知道它是多麼普遍。

代碼

def arrayify(str) 
    eval('['+str.gsub(/(\w+)\s+\(/,'{\1=>[') 
    .gsub(/(?!\{)(\w+)\s+/, '{\1=>nil},') 
    .gsub(')', ']}') 
    .gsub(/\b(\w+)\b/,"\"\\1\"")+']') 
end 

str = "Animals (Reptiles Birds (Eagles Pigeons Crows))" 
arrayify(str) 
    #=> [{ "Animals"=>[{ "Reptiles"=>"nil"}, 
    #     { "Birds" =>[{ "Eagles" =>"nil" }, 
    #         { "Pigeons"=>"nil" }, 
    #         { "Crows" =>"nil" } 
    #        ] 
    #     } 
    #     ] 
    # } 
    # ] 

說明

s1 = str.gsub(/(\w+)\s+\(/,'{\1=>[') 
    #=> "{Animals=>[ Reptiles {Birds=>[ Eagles Pigeons Crows))" 
s2 = s1.gsub(/(?!\{)(\w+)\s+/, '{\1=>nil},') 
    #=> "{Animals=>[ {Reptiles=>nil},{Birds=>[ {Eagles=>nil},{Pigeons=>nil},{Crows=>nil},))" 
s3 = s2.gsub(')', ']}') 
    #=> "{Animals=>[ {Reptiles=>nil},{Birds=>[ {Eagles=>nil},{Pigeons=>nil},{Crows=>nil},]} ]}" 
s4 = s3.gsub(/\b(\w+)\b/,"\"\\1\"") 
    #=> "{\"Animals\"=>[ {\"Reptiles\"=>\"nil\"},{\"Birds\"=>[ {\"Eagles\"=>\"nil\"},{\"Pigeons\"=>\"nil\"},{\"Crows\"=>\"nil\"},]} ]}" 
eval('['+s4+']') 
    #=> <result in example> 

原諒我,但我必須跑。 eval警察即將到來。