我正在编写一个程序来解析一个基本的文本文件,并将其中的某些行与测试结果进行比较。我使用特定的单词来查找应与测试结果进行比较的行,然后根据该行是否与结果匹配(它们应该完全相同(通过或失败结果。我使用以下常规格式:
File.open(file).each do |line|
if line include? "Revision"
if line==result
puts "Correct"
else
puts "Fail"
大多数情况只是一行,所以这很容易。但是对于少数情况,我的结果是 4 行长,而不仅仅是一行。因此,一旦找到我需要的行,我需要检查结果是否等于感兴趣的行加上后面的以下 3 行。这是正在读取的文件中信息的格式,以及测试结果的外观:
Product Serial Number: 12058-2865
Product Part Number: 3456
Product Type: H-Type
Product Version: 2.07
找到兴趣线后,我只需要将兴趣线加上接下来的三行与整个结果进行比较。
if line include? "Product Serial Number"
#if (#this line and the next 3) == result
puts Correct
else
puts "Fail"
我该怎么做?
text =<<_
My, oh my
Product Serial Number: 12058-2865
Product Part Number: 3456
Product Type: H-Type
Product Version: 2.07
My, oh my
Product Serial Number: 12058-2865
Product Part Number: 3456
Product Type: H-Type
Product Version: 2.08
My, ho my
Product Serial Number: 12058-2865
Product Part Number: 3456
Product Type: H-Type
Product Version: 2.07
_
result =<<_.lines
Product Serial Number: 12058-2865
Product Part Number: 3456
Product Type: H-Type
Product Version: 2.07
_
#=> ["Product Serial Number: 12058-2865n", "Product Part Number: 3456n",
# "Product Type: H-Typen", "Product Version: 2.07n"]
FName = "test"
File.write(FName, text)
#=> 339
target = "Product Serial Number"
nbr_result_lines = result.size
#=> 4
lines = File.readlines(FName)
#=> ["My, oh myn",
# "Product Serial Number: 12058-2865n",
# ...
# "Product Version: 2.07n"]
lines.each_with_index do |line, i|
(puts (lines[i, nbr_result_lines] == result ? "Correct" : "Fail")) if
line.match?(target)
end
# "Correct"
# "Fail"
# "Correct"
请注意,当数组足够大时,数组lines[i, nbr_result_lines]
将以一个或多个nil
结束i
。
如果文件太大,以至于将其压缩到数组中是不可取或不可行的,则可以
- 将第一个
nbr_result_lines
读入缓冲区(例如,使用 IO::foreach(; target
与缓冲区的第一行进行比较,如果匹配,则result
与缓冲区进行比较;
删除缓冲区的第一行,将- 文件的下一行添加到缓冲区的末尾并重复上述操作,直到将文件的最后一行添加到缓冲区后检查缓冲区为止。
存在类似的答案问题:一次阅读多行
我认为如果您有已知格式的文件并且具有持久性系列行,则可以将乘行读取到数组中,并使用所需的逻辑迭代数组元素。
File.foreach("large_file").each_slice(8) do |eight_lines| # eight_lines is an array containing 8 lines. # at this point you can iterate over these lines end
是的,循环循环不是很好,但最好乘以if else
好吧,你可以有几种方法,简单的方法是遍历每一行。 并尝试像这样检测序列,它应该类似于用于检测序列的状态机:
step = 0
File.open('sample-file.txt').each do |line|
if /^Product Serial Number.*/.match? line
puts(step = 1)
elsif /^Product Part Number.*/.match?(line) && step == 1
puts(step = 2)
elsif /^Product Type.*/.match?(line) && step == 2
puts(step = 3)
elsif /^Product Version.*/.match?(line) && step == 3
puts 'correct'
puts(step = 0)
else
puts(step = 0)
end
end
有了这个结果:
ruby read_file.rb
1
2
3
correct
0
0
1
0
0
0
0
0
0
1
2
3
correct
0
0
和此示例文件:
Product Serial Number: 12058-2865
Product Part Number: 3456
Product Type: H-Type
Product Version: 2.07
no good line
Product Serial Number: 12058-2865
BAD Part Number: 3456
Product Type: H-Type
Product Version: 2.07
no good line
no good line
no good line
Product Serial Number: 12058-2865
Product Part Number: 3456
Product Type: H-Type
Product Version: 2.07
no good line