我想将此字符串文本转换为基于用户输入创建页面的散列。将文本解析为二维散列
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