如何在Ruby中一次访问多行

时间:2018-10-16 15:54:07

标签: ruby file-io fileparsing

我正在编写一个程序来解析基本文本文件,并将其中的某些行与测试结果进行比较。我使用特定的单词来查找应该与测试结果进行比较的行,然后根据行是否与结果匹配(它们应该完全相同)来通过或失败结果。我正在使用以下常规格式:

File.open(file).each do |line|
  if line include? "Revision"
    if line==result
     puts "Correct"
    else
     puts "Fail"

大多数情况只是一行,所以这很容易。但是在某些情况下,我的结果是4行,而不仅仅是1行。因此,一旦找到所需的行,就需要检查结果是否等于感兴趣的行加上其后的以下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"

我该怎么做?

3 个答案:

答案 0 :(得分:0)

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-2865\n", "Product Part Number: 3456\n",
#    "Product Type: H-Type\n", "Product Version: 2.07\n"]

FName = "test"
File.write(FName, text)
  #=> 339
target = "Product Serial Number"

nbr_result_lines = result.size
  #=> 4
lines = File.readlines(FName)
  #=> ["My, oh my\n",
  #    "Product Serial Number: 12058-2865\n",
  #    ...
  #    "Product Version: 2.07\n"]
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与缓冲区进行比较;
  • 删除缓冲区的第一行,将文件的下一行添加到缓冲区的末尾,然后重复上述操作,直到将文件的最后一行添加到缓冲区中之后,继续检查缓冲区。 / li>

答案 1 :(得分:0)

您可以有几种方法,简单的方法是遍历每一行。并尝试像这样检测序列,它应该类似于状态机来检测序列:

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

答案 2 :(得分:0)

存在类似的已回答问题:reading a mulitply lines at once

我认为,如果您拥有格式已知的文件并坚持了一系列行,则可以读取乘以行的数组,并使用所需的逻辑遍历数组元素。

  

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

Yep循环不是很好,但是最好乘以if else