2014-08-28 2 views
-2

У меня есть файл, как это:Рубин - Получить содержимое файла с в сепараторе в массиве

some content 

some oterh 

********************* 

useful1 text 

useful3 text 

********************* 
some other content 

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

a=["useful1 text" , "useful2 text"] 

ответ

2

А действительно взломать решение разделить линии на звезды, возьмите среднюю часть, а затем разделить это тоже:

content.split(/^\*+$/)[1].split(/\s+/).reject(&:empty?) 
# => ["useful1","useful3"] 
+0

Я получаю содержимое как этот контент = File.open ("somefilename.txt"). Это дает мне ошибку неопределенного разделения метода. Каков правильный способ получить контент. – user1788294

+0

'File.read (...)' также выполнит эту работу. Если вы получаете неопределенный метод, возможно, вы ничего не получите для «контента»? – tadman

+0

Я проверил содержимое не пустым. Кажется, что-то здесь отсутствует. – user1788294

0

Что об этом:

def values_between(array, separator) 
    array.slice array.index(separator)+1..array.rindex(separator)-1 
end 

filepath = '/tmp/test.txt' 
lines  = %w(trash trash separator content content separator trash) 
separator = "separator\n" 

File.write '/tmp/test.txt', lines.join("\n") 
values_between File.readlines('/tmp/test.txt'), "separator\n" 
#=> ["content\n", "content\n"] 
+0

Когда я использую lines = "trash trash separator content content separator trash", почему я не получаю правильный результат. – user1788294

+2

@ user1788294 Потому что вы взяли его сообщение буквально, а не адаптировали его к тому, что вам действительно нужно? –

1
f = File.open('test_doc.txt', 'r') 
content = [] 
f.each_line do |line| 
    content << line.rstrip unless !!(line =~ /^\*(\*)*\*$/) 
end 
f.close 

регулярное выражение шаблон/^ * (*) * $/MATC которые содержат только звездочки. !! (line = ~/^ * (*) * $ /) всегда возвращает логическое значение. Поэтому, если шаблон не соответствует, строка добавляется в массив.

+0

Это добавит все строки, которые не соответствуют звездному шаблону. Даже заголовок и трейлер. Это, вероятно, не соответствует ожиданиям OP: s. –

+0

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

0

Я хотел бы сделать это следующим образом:

lines = [] 
File.foreach('./test.txt') do |li| 
    lines << li if (li[/^\*{5}/] ... li[/^\*{5}/]) 
end 

lines[1..-2].map(&:strip).select{ |l| l > '' } 
# => ["useful1 text", "useful3 text"] 

/^\*{5}/ означает «Строка, которая начинается с и имеет, по меньшей мере, пять„*

... является одним из двух видов использования .. и .... и, в этом использовании, обычно называют оператором «триггера». Он часто не используется в Ruby, потому что большинство людей, похоже, не понимают его. Иногда ошибочно принимают разделители Range .. и ....

В этом использовании, Ruby часы для первого теста, li[/^\*{5}/], чтобы вернуть true. Как только это произойдет, .. или ... вернет true, пока второе условие не вернет true. В этом случае мы ищем один и тот же разделитель, поэтому один и тот же тест будет работать, li[/^\*{5}/], и именно здесь вступает в игру разница между двумя версиями: .. и ....

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

Это позволяет тест назначить lines, который до [1..-2].map(&:strip).select{ |l| l > '' } выглядит как:

# => ["*********************\n", 
#  "\n", 
#  "useful1 text\n", 
#  "\n", 
#  "useful3 text\n", 
#  "\n", 
#  "*********************\n"] 

[1..-2].map(&:strip).select{ |l| l > '' } очищает, что до нарезки массива, чтобы удалить первые и последние элементы, strip удаляет начальные и конечные пробела , эффективно избавляясь от завершающих строк новой строки и вызывая пустые строки и строки, содержащие нужный текст. select{ |l| l > '' } берет линии, которые больше, чем «пустые» строки, т. Е. Не пустые.

См. «When would a Ruby flip-flop be useful?» и связанные с ним вопросы, а также «What is a flip-flop operator?» для получения дополнительной информации и некоторого фона. (Программисты Perl используют .. и ... часто для этой цели.)

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

Смежные вопросы