我想將此字符串文本轉換爲基於用戶輸入創建頁面的散列。將文本解析爲二維散列
Home
About
- News
-- Local News
-- Global News
- Who We Are
Product
這只是一個例子,但我想將它轉換爲我可以遍歷的多維散列。我想創建一個簡單的方式讓用戶在CMS中創建頁面。
我玩過分裂字符串和正則表達式,但我還沒有走過。
任何幫助將不勝感激!
我想將此字符串文本轉換爲基於用戶輸入創建頁面的散列。將文本解析爲二維散列
Home
About
- News
-- Local News
-- Global News
- Who We Are
Product
這只是一個例子,但我想將它轉換爲我可以遍歷的多維散列。我想創建一個簡單的方式讓用戶在CMS中創建頁面。
我玩過分裂字符串和正則表達式,但我還沒有走過。
任何幫助將不勝感激!
這是我的嘗試。我完全承認它看起來不太習慣,並且在ruby stdlib中可能會有一行代碼可以替代它。但是,嘿,至少這個工程:)
所以,基本的思路是這樣的:
代碼:
txt = <<-TXT
Home
About
- News
-- Local News
-- Global News
- Who We Are
Product
TXT
def lines_to_hash lines
res = {}
last_level = 0
parent_stack = [res]
last_line = nil
lines.each do |line|
cur_level = line.scan('-').length
if cur_level > last_level
parent_stack << parent_stack.last[last_line]
elsif cur_level < last_level
parent_stack.pop
end
clean_line = line.gsub(/^[-\s]+/, '')
parent_stack.last[clean_line] = {}
last_line = clean_line
last_level = cur_level
end
res
end
res = lines_to_hash(txt.split("\n"))
res # => {"Home"=>{},
# "About"=>{"News"=>{"Local News"=>{}, "Global News"=>{}},
# "Who We Are"=>{}},
# "Product"=>{}}
如果有人想出了一個俏皮話,我會獎勵+100代表在賞金:)
[Challenge accepted!](http://stackoverflow.com/questions/14280573/parsing-text-into-dimensional-hash/14282912#14282912) –
看起來YAML會成爲你的朋友。看看Yaml.load。 test.yml:
"Home":
"About":
"News":
"Local News":
"Global News":
"Who We Are":
"Products":
IRB
require 'yaml'
YAML.load(File.open('test.yml'))
=> {"home"=>{"About"=>{"News"=>{"Local News"=>nil, "Global News"=>nil, "Who We Are"=>nil}}, "Product"=>nil}}
只想添加:如果你想做一個解析器你可以看看[Parslet](http://kschiess.github.com/parslet/) –
這看起來像一個很酷的圖書館! – plasticide
由於[Rails剛剛發現](http://blog.codeclimate.com/blog/2013/01/10/rails-remote-code-execution-vulnerability-explained/),如果你想要非常小心'要去'YAML.load'任何用戶可編輯的! –
txt = <<-TXT
Home
About
- News
-- Local News
-- Global News
- Who We Are
Product
TXT
def hashify s
Hash[s.split(/^(?!-)\s*(.*)/).drop(1).each_slice(2).map{|k, v| [k, hashify(v.to_s.strip.gsub(/^-/, ""))]}]
end
hashify(txt)
# =>
# {
# "Home" => {},
# "About" => {
# "News" => {
# "Local News" => {},
# "Global News" => {}
# },
# "Who We Are" => {}
# },
# "Product" => {}
# }
@Sergio:這是一個一行! (誠然,我已經把它分割到幾個線「清晰度」)
@ LT-matt8:如果你確實使用此然後,我要爲未來的人的理智概不負責稍後閱讀你的代碼:)
text = <<-TEXT
Home
About
- News
-- Local News
-- Global News
- Who We Are
Product
TEXT
hash = text.lines.each_with_object([{}]) {|item, levels|
item.match(/(-*)\s*(.*)/).captures.tap {|level, title|
levels[level.size][title] = (levels[level.size + 1] = {})
}
}.first
# => {"Home"=>{}, "About"=>{"News"=>{"Local News"=>{}, "Global News"=>{}}, "Who We Are"=>{}}, "Product"=>{}}
雖然您的答案在技術上符合條件,但@ sawa的答案更短。他的職位更老了。 –
無論如何,我將不得不等待2天才能開始賞金。 –
哦同意了,@ sawa的好多了。我只是試圖在沒有遞歸的情況下做到這一點 - 如果你必須定義一個方法,它在技術上仍然是一個單線程? ;) –
顯示您嘗試過的一些代碼。 –
什麼是多維散列? – sawa
@sawa這是一個哈希值,它具有其他哈希值。嵌套散列是它的另一個術語。你可以在下面的答案中看到示例(方法的輸出) – plasticide