Multi-level 正在解析文本
Multi-level parsing text
上次遇到问题:
现在我想象复杂的情况。
例如。我有一个文本文件,下一个包含:
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"可能?
在 each
块中声明的变量不会在迭代之间保留。当迭代结束时,这些变量就会消失,这就是为什么您会丢失之前的 sub
值。要修复它,请将 sub
变量移动到外部范围,方法是在 each
之前对其进行初始化,就像 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
如果你想在两次迭代之间保留变量,你可以使用实例变量。
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
上次遇到问题:
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"可能?
在 each
块中声明的变量不会在迭代之间保留。当迭代结束时,这些变量就会消失,这就是为什么您会丢失之前的 sub
值。要修复它,请将 sub
变量移动到外部范围,方法是在 each
之前对其进行初始化,就像 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
如果你想在两次迭代之间保留变量,你可以使用实例变量。
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