Как я могу gsub все до следующей пустой строки?

Учитывая эту строку:

bc.  some text
 more text
 even more

^ above here is the empty line

Я хочу, чтобы это было:

<pre>
some text
more text
even more
</pre>

^ above here is the empty line

Как я могу использовать регулярное выражение для "начиная с bc. до первой пустой строки"?

Пока я получил это:

# note that for some reason a direct .gsub! behaves
# differently/fails when using the block, so I use .gsub
textile_markup = textile_markup.gsub(/^bc.  .*^$/m) { |s| "<pre>#{s[5..(s.length)]}</pre>" }

Понятно, что это соответствует жадно до самой последней пустой строки, а не до первой. Как сделать часть ^$ не жадной?


person user569825    schedule 19.03.2013    source источник
comment
Обычно .*? является нежадной версией .*. Будет ли это работать?   -  person tadman    schedule 19.03.2013
comment
вам понадобится модификатор /s для точки, чтобы соответствовать новым строкам   -  person Lodewijk Bogaards    schedule 19.03.2013
comment
У вас есть только один блок или это повторяющийся шаблон через строку/файл? Если это повторяется, вам нужно представить это в ваших примерах данных. Кроме того, почему это должно быть сделано с использованием регулярного выражения?   -  person the Tin Man    schedule 19.03.2013
comment
Вы знаете этот замечательный сайт под названием rubular? rubular.com/r/uloTda090y   -  person phoet    schedule 19.03.2013
comment
@theTinMan У меня есть только один блок. Я также открыт для более эффективных решений. Однако я думаю, что кратчайший путь будет регулярным выражением.   -  person user569825    schedule 20.03.2013
comment
@phoet Спасибо за подсказку на сайте. Однако пример сопоставления не соответствует моему примеру кода. См. здесь: rubular.com/r/Tz5MuKg41z (извините также за путаницу - я обновил образец до отображать последнюю строку после закрывающего </pre>.   -  person user569825    schedule 20.03.2013
comment
@user569825 user569825 нет необходимости использовать gsub целиком! используйте группу совпадений, а затем поместите все на свои места   -  person phoet    schedule 20.03.2013
comment
@phoet Мне трудно понять предложенную вами идею. Не могли бы вы обновить пример, который вы разместили, чтобы отразить его?   -  person user569825    schedule 20.03.2013
comment
@ user569825 посмотрите документы apidock.com/ruby/String/match   -  person phoet    schedule 20.03.2013


Ответы (2)


str = 
"bc.  some text
more text
even more

^ above here is the empty line

bc.  some text
more text
even more

^ above here is the empty line"

puts str.gsub(/^bc\.  (.*?)\n\n/m, "<pre>\n\\1\n</pre>\n\n")

Выход:

<pre>
some text
more text
even more
</pre>

^ above here is the empty line

<pre>
some text
more text
even more
</pre>

^ above here is the empty line

Объяснение

? в .*? делает звездного оператора не жадным

Модификатор /m в конце заставляет точки совпадать с новыми строками

person Yuri Golobokov    schedule 20.03.2013
comment
Документы, которые я тестировал до сих пор, отлично работают с этим кодом. Благодарю вас! - person user569825; 21.03.2013

Это можно сделать за один раз, но для этого требуется некоторая подготовка:

txt = <<DOC
bc.  some text
 more text
 even more

bc.  some text
 more text
 even more

DOC

TRANSFORMS = {"bc.  " => "<pre>\n",       # The 'bc.  should become <pre> followed by a line-end
              /^ /    => "",              # leading space should be eliminated
             "\n\n"   => "\n<\/pre>\n\n"} # empty line should be preceded by a closing pre-tag

re = Regexp.union(TRANSFORMS.keys)
puts txt.gsub(re, TRANSFORMS)

Выход:

<pre>
some text
more text
even more
</pre>

<pre>
some text
more text
even more
</pre>
person steenslag    schedule 19.03.2013
comment
Мне очень нравится, как вы это закодировали! Замены применимы и в других ситуациях, которых я хочу избежать, так как работаю с огромными документами. Вариант Юрия Голобокова gsub работает, и я думаю, что всем было бы интересно увидеть его в вашем стиле, если это возможно. Было бы здорово, если бы вы обновили. - person user569825; 21.03.2013
comment
Он добавит "\n<\/pre>\n\n" для каждой пустой строки, даже если абзац не был начат с bc. - person Yuri Golobokov; 21.03.2013