Как получить доступ к нескольким строкам одновременно в ruby - PullRequest
0 голосов
/ 16 октября 2018

Я пишу программу для анализа основного текстового файла и сравнения определенных строк из него с результатами теста.Я использую определенные слова, чтобы найти строку, которую следует сравнить с результатом теста, а затем пропускаю или не получаю результат в зависимости от того, соответствует ли строка результату (они должны быть точно такими же).Я использую следующий общий формат:

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"

Как мне это сделать?

Ответы [ 3 ]

0 голосов
/ 16 октября 2018

Ну, у вас может быть несколько подходов для этого, самый простой способ - пройти каждую строку.и попытайтесь определить последовательность, подобную этой, это должно быть что-то похожее на конечный автомат для обнаружения последовательности:

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
0 голосов
/ 16 октября 2018

Существует аналогичный ответ на вопрос: чтение нескольких строк сразу

Я думаю, что если у вас есть файл с известным форматом и у вас есть постоянный ряд строк, вы можете прочитать несколько строк длямассив и итерации по элементам массива с необходимой логикой.

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

0 голосов
/ 16 октября 2018
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 с буфером;
  • удалить первую строку буфера, добавить следующую строкуфайл до конца буфера и повторяйте вышеизложенное, продолжая до тех пор, пока буфер не будет проверен после добавления в него последней строки файла.
...