2017-02-28 40 views
0

我最后一次遇到问题: Parsing and structuring of a text file 现在我想象一下复杂的情况。例如, 。我有一个包含下一个文本文件:多级解析文本

Head 1 
Subhead 1 
a 10 
b 14 
c 88 
Subhead 2 
a 15 
b 16 
c 17 
d 88 
Subhead 3 
a 55 
b 36 
c 87 
Head 4 
Subhead 1 
r 32 
t 55 
s 79 
r 22 
t 88 
y 53 
o 78 
p 90 
m 44 
Head 53 
Subtitle 1 
y 22 
b 33 
Subtitle 2 
a 88 
g 43 
r 87 
Head 33 
Subhead 1 
z 11 
d 66 
v 88 
b 69 
Head 32 
Subhead 1 
n 88 
m 89 
b 88 
Subhead 2 
b 88 
m 43 

现在我需要结构文本到下一个平面。我想得到下一个数据:

Head 1, Subhead 1, c 88 
Head 1, Subhead 2, d 88 
Head 4, Subhead 1, t 88 
Head 53, Subhead 2, a 88 
Head 33, Subhead 1, v 88 
Head 32, Subhead 1, n 88 
Head 32, Subhead 1, b 88 
Head 32, Subhead 2, b 88 

也就是说,我想要得到所有的行,其中88表示头和小标题。

我的行为:

lines = File.open("file.txt").to_a 
lines.map!(&:chomp) # remove line breaks 

current_head = "" 
res = [] 

lines.each do |line| 
    case line 
    when /Head \d+/ 
    current_head = line 
    when /Subhead/ 
    sub = line 
    when /\w{1} 88/ 
    num = line 
    res << "#{current_head}, #{sub}, #{num}" 
    end 
end 

puts res 

当我用这个方法我没有得到NUM值的字符串。

是否执行我的任务意味着“case when”可能?

回答

0

each块中声明的变量在迭代之间不会保留。当迭代结束时,这些变量消失,这就是为什么你失去了以前的sub值。为了解决这个问题,由each之前对其进行初始化移动sub变量外的范围,就像你有current_head

current_head = "" 
current_sub = "" 
res = [] 

lines.each do |line| 
    case line 
    when /Head \d+/ 
    current_head = line 
    when /Subhead/ 
    current_sub = line 
    when /\w{1} 88/ 
    num = line 
    res << "#{current_head}, #{current_sub}, #{num}" 
    end 
end 

看到它在repl.it:https://repl.it/GBKn

+0

谢谢您的解决方案! – Misha1991

0

如果你想保留两次迭代之间的变量,你可以使用实例变量。

File.foreach是读取文件的推荐方式:

res = [] 
File.foreach("file.txt") do |line| 
    line.chomp! 
    case line 
    when /Head \d+/ 
    @current_head = line 
    when /Sub(head|title)/ 
    @sub = line 
    when /\w 88/ 
    num = line 
    res << "#{@current_head}, #{@sub}, #{num}" 
    end 
end 
puts res 
+0

谢谢你的解决方案! foreach真的很方便 – Misha1991