2016-11-15 3 views
0

Мне нужна помощь, и я использую 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

Вы хотите получить все, что имеет значение «88»? Это непонятно из вопроса. Также, пожалуйста, покажите нам, что вы уже пробовали. – mudasobwa

+0

@il_raffa Спасибо за редактирование – Misha1991

+0

@Mudasobwa Да, я хочу выбрать все записи с 88 и их заголовками – Misha1991

ответ

1

Если ответ на вопрос @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 
+0

Да, вы будете правы! Спасибо вам! – Misha1991

+0

Это лучший подход, ими. У меня есть несколько предложений. 1. Используйте 'File.foreach ('file.txt'). With_object ([]) do | line, res |' вместо всех строк через 'lines.each do | line |'. 'with_object ([])' инициализирует 'res' и вызывает возврат блока' res'. 2. Не нужно инициализировать 'current_head'. 3.'\ w {1}' - это то же самое, что и '\ w', но вы можете быть более конкретным, например, используя' [[: lower:]] 'или' [[: lower:]] + '. 4. После 'when/Head \ d + /' возможно написать 'head = line; когда/[[: lower:]] + \ s + 88 /; res << "# {head.chomp}, # {line.chomp}"; end'. –

+0

@CarySwoveland вы правы, я написал решение для начинающего уровня, но да, у вас есть профессиональное решение. –

1

Я написал свои данные в файл «Темп»:

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

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 ассоциировать каждую «голову» с всеми строками следующим образом (до следующего «Head» или конца файла), что в конечный 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"] 
Смежные вопросы