Разбор и структурирование текстового файла
Мне нужна помощь, и я использую 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"]