问题
The last time I had a problem: Parsing and structuring of a text file Now I imagine complicated conditions. For example. I had a text file with next contain:
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
Now I need structure text to next plane. I want to get next data:
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
That is, I want to get all the rows with 88 indicating the head and subhead.
My actions:
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
When I use this method I get a string without NUM values.
Whether to perform my task means "case when" possible?
回答1:
The variables declared inside the each
block do not persist between iterations. When the iteration ends, those variables disappear, which is why you're losing the previous sub
value. To fix it, move the sub
variable to the outer scope by initializing it before the each
, just like you have with 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
See it on repl.it: https://repl.it/GBKn
回答2:
If you want to keep variables between two iterations, you could use instance variables.
File.foreach
is the recommended way of reading a file :
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
来源:https://stackoverflow.com/questions/42513224/multi-level-parsing-text