Разбор и структурирование текстового файла

Мне нужна помощь, и я использую Ruby. У меня был текстовый файл со следующим содержанием:

Head 1
a 10
b 14
c 15
d 16
e 17
f 88
Head 4
r 32
t 55
s 79
r 22
t 88
y 53
o 78
p 90
m 44
Head 53
y 22
b 33
Head 33
z 11
d 66
v 88
b 69
Head 32
n 88
m 89
b 88

И я хочу разобрать и структурировать этот файл на следующую плоскость. Я хочу получить следующие данные:

Head 1, f 88
Head 4, t 88
Head 33, v 88
Head 32, n 88
Head 32, b 88

Подскажите пожалуйста, как мне сделать такой код на рубине?

Я думаю, что сначала я положил все строки в массиве:

lines = Array.new
File.open('C:/file/file.txt', 'r').each { |line| lines << line }

но что мне делать дальше?

Спасибо!

2 ответа

Решение

Если ответ на вопрос @mudasobwa "Хотите ли вы получить все, что имеет значение 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 /\w{1} 88/
    res << "#{current_head}, #{line}"
  end
end

puts res

Я записал ваши данные в файл 'temp':

Сначала определите регулярное выражение для извлечения интересующих строк файла.

r = /
    Head\s+\d+        # match 'Head', > 0 spaces, ?= 1 digits in capture group 1
    |                 # or
    [[:lower:]]+\s+88 # match > 0 lower case letters, > 0 spaces, '88'
    /xm               # free-spacing regex definition and multi-line modes

Теперь выполните следующие операции с файлом.

File.read('temp').scan(r).
                  slice_before { |line| line.start_with?('Head ') }.
                  reject { |a| a.size == 1 }.
                  flat_map { |head, *rest| [head].product(rest) }.
                  map { |a| "%s, %s" % a }
  #=> ["Head 1, f 88", "Head 4, t 88", "Head 33, v 88",
  #    "Head 32, n 88", "Head 32, b 88"]

Шаги следующие.

a = File.read('temp').scan(r)
  #=> ["Head 1", "f 88", "Head 4", "t 88", "Head 53", "Head 33",
  #    "v 88", "Head 32", "n 88", "b 88"]
b = a.slice_before { |line| line.start_with?('Head') }
  #=> #<Enumerator: #<Enumerator::Generator:0x007ffd218387b0>:each> 

Мы можем видеть элементы, которые будут сгенерированы перечислителем b преобразовав его в массив.

b.to_a
  #=> [["Head 1", "f 88"], ["Head 4", "t 88"], ["Head 53"],
  #    ["Head 33", "v 88"], ["Head 32", "n 88", "b 88"]]

Теперь удалите все массивы размера 1 из b,

c = b.reject { |a| a.size == 1 }
  #=> [["Head 1", "f 88"], ["Head 4", "t 88"], ["Head 33", "v 88"],
  # ["Head 32", "n 88", "b 88"]]

Затем мы используем Enumerable # flat_map и Array # product, чтобы связать каждую "Голову" со всеми строками, следующими за (до следующей "Головы" или конца файла), которые заканчиваются 88\n,

d = c.flat_map { |head, *rest| [head].product(rest) }
  #=> [["Head 1", "f 88"], ["Head 4", "t 88"], ["Head 33", "v 88"],
  #    ["Head 32", "n 88"], ["Head 32", "b 88"]]

Наконец, преобразовать каждый элемент d в строку.

d.map { |a| "%s, %s" % a }
  #=> ["Head 1, f 88", "Head 4, t 88", "Head 33, v 88",
  #    "Head 32, n 88", "Head 32, b 88"] 
Другие вопросы по тегам