2012-08-01 23 views
1

这可能是一个更一般的编程问题,但我想知道红宝石的最佳做法是在解决这个问题。我想分析的一些结构像这样的文件:在包含.each_line的红宝石循环中提前行号码

toplevel blah blah 0 
    attr0: foo 
    attr1: bar 
    nextlevel something 0 
    child0: baz 
    child1: boz 
     var1: blah  
    nextlevel something 1 
    child0: faz 
     abc: yes 
    child1: foz 

我采用分体式和解析出数据块或可能迭代与.each_line该文件,然后莫名其妙地认为(我不知道怎么做)做嵌套迭代

嵌套线,我想,会是这个样子:

input.each_line do |line| 
    #parse attributes 
    if line =~ /nextlevel:\s+(\d)/ then 
    #now advance the line count somehow and continue parsing in here 
    end 

PS对不起,如果这个例子中的名字有点杂乱,但我想要制作一个简化的MWE。

+0

是不是“先行计数”只是'line_count + = 1'或..? ;-) – 2012-08-01 22:05:25

+1

无论如何,我会*不*使用'each_line',而是将(打开的)文件传递给*递归函数*,并且每个函数根据需要使用这些行。它看起来像缩进(或缺乏)确定基础和递归情况。 – 2012-08-01 22:06:11

+0

此外,它看起来可以摆弄(或写入)[YAML](http://corelib.rubyonrails.org/classes/ YAML.html)或其他标记格式(基于偏好?)和*然后*消耗..?使用现有的工具是最容易的,同时也减少了“新的一次性格式”的引入。 – 2012-08-01 22:07:53

回答

2

这是你想提取类型的结构?

def parse(inp, level) 
    until inp.eof? 
     line = inp.gets 
     if line =~ /nextlevel:\s+(\d)/ 
      parse(inp, $1.to_i) 
     else 
      puts "got line: '#{line.strip}' at level #{level}" 
     end 
    end 
end 

irb(main):070:0> parse(input, -1) 
got line: 'toplevel: 0' at level -1 
got line: 'attr0: foo' at level -1 
got line: 'attr1: bar' at level -1 
got line: 'child0: baz' at level 0 
got line: 'child1: boz' at level 0 
got line: 'child0: faz' at level 1 
got line: 'child1: foz' at level 1 
=> nil 

此使用递归方法来跟踪使用堆栈的深度,但它也同样简单,做这样使用变量和迭代的方法。

+0

这肯定有帮助,不幸的是,格式更加随意。不过,我可能能够拿走你所拥有的东西,并计算空白空间或其他东西。我希望我可以复制+粘贴实际输出,但不允许 – zje 2012-08-06 13:57:51

+1

我想帮助您更多,但我仍不清楚您尝试从文件中提取的结构。如果您可以举一个例子说明您希望程序的输出结果如何,那么我可以帮助您概述您的ruby需要的外观。 – Zach 2012-08-06 21:23:44

+0

感谢您的帮助,并为分享详细信息的麻烦感到抱歉。基本上,我希望最终从这些数据中构建一个散列或其他类型的结构来表示样本输入数据中显示的层次结构。在我正在处理的输出中,对于每个级别有什么期待的预定义概念 - 所以我可以为每个级别创建一个单独的对象并适当地填充它们,计算空白以确定级别。 – zje 2012-08-07 13:07:07