Регулярные выражения: как получить блок текста с помощью регулярных выражений?(в рубине) - PullRequest
3 голосов
/ 04 октября 2010

Я использую ruby ​​и пытаюсь найти способ перехватить текст между {start_grab_entries} и {end_grab_entries}, например так:

{start_grab_entries}
i want to grab
the text that
you see here in
the middle
{end_grab_entries}

Примерно так:

$1 => "i want to grab
       the text that
       you see here in
       the middle"

До сих пор я пробовал это как свое регулярное выражение:

\{start_grab_entries}(.|\n)*\{end_grab_entries}

Однако, используя 1 доллар, я получаю пробел.Знаете ли вы, что я могу сделать, чтобы правильно захватить этот блок текста между тегами?

Ответы [ 3 ]

7 голосов
/ 04 октября 2010

Есть лучший способ разрешить точке совпадать с новыми строками (/m модификатор):

regexp = /\{start_grab_entries\}(.*?)\{end_grab_entries\}/m

Кроме того, сделайте * ленивым, добавив ?, или вы можете совпастьслишком много, если в вашем входе более одного такого раздела.

Тем не менее, причина, по которой вы получили пустое совпадение, состоит в том, что вы повторили саму группу захвата ;поэтому вы поймали только последнее повторение (в данном случае, \n).

Это бы "сработало", если бы вы поместили группу захвата вне повторения:

\{start_grab_entries\}((?:.|\n)*)\{end_grab_entries\}`

но, как сказано выше, есть лучший способсделать это.

1 голос
/ 04 октября 2010

Я добавляю это, потому что часто мы читаем данные из файла или потока данных, где диапазон строк, который мы хотим, не все в памяти одновременно. «Прихлебывать» файл не рекомендуется, если данные могут превысить доступную память, что легко происходит в производственных корпоративных средах. Вот как мы просматриваем строки между некоторыми граничными маркерами во время сканирования файла. Он не опирается на регулярные выражения, вместо этого используется оператор "Ruby-flop" ..:

#!/usr/bin/ruby

lines = []
DATA.each_line do |line|
  lines << line if (line['{start_grab_entries}'] .. line['{end_grab_entries}'])
end

puts lines          # << lines with boundary markers
puts
puts lines[1 .. -2] # << lines without boundary markers

__END__
this is not captured

{start_grab_entries}
i want to grab
the text that
you see here in
the middle
{end_grab_entries}

this is not captured either

Вывод этого кода будет выглядеть так:

{start_grab_entries}
i want to grab
the text that
you see here in
the middle
{end_grab_entries}

i want to grab
the text that
you see here in
the middle
1 голос
/ 04 октября 2010
string=<<EOF
blah
{start_grab_entries}
i want to grab
the text that
you see here in
the middle
{end_grab_entries}
blah
EOF

puts string.scan(/{start_grab_entries}(.*?){end_grab_entries}/m)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...