Регулярное выражение для сопоставления блока текста с первой двойной новой строкой?


Я создаю простой синтаксический анализатор текстиля и пытаюсь написать регулярное выражение для "blockquote", но у меня возникают трудности с сопоставлением нескольких новых строк. Пример:

bq. first line of quote
second line of quote
third line of quote

not part of the quote

Он будет заменен тегами blockquote через preg_replace(), поэтому в основном он должен соответствовать всему, что находится между "bq." и первой двойной новой строкой, с которой он сталкивается. Лучшее, что я могу сделать, - это получить первую строку цитаты. Спасибо

Author: Tomalak, 2010-02-08

5 answers

Попробуйте это регулярное выражение:

(?s)bq\.((?!(\r?\n){2}).)*+

Значение:

(?s)           # enable dot-all option
b              # match the character 'b'
q              # match the character 'q'
\.             # match the character '.'
(              # start capture group 1
  (?!          #   start negative look ahead
    (          #     start capture group 2
      \r?      #       match the character '\r' and match it once or none at all
      \n       #       match the character '\n'
    ){2}       #     end capture group 2 and repeat it exactly 2 times
  )            #   end negative look ahead
  .            #   match any character
)*+            # end capture group 1 and repeat it zero or more times, possessively

\r?\n соответствует разрывам строк Windows, *nix и (более новых) macOS. Если вам нужно учитывать реальные старые компьютеры Mac, добавьте к нему один \r: \r?\n|\r

 6
Author: Bart Kiers, 2010-02-08 14:59:04

Этот принятый ответ захватил для меня только последний символ блока. В итоге я использовал это:

$text =~ /(?s)bq\.(.+?)\n\n/g
 1
Author: Michael Keating, 2015-11-11 23:18:57

Сработает ли это?

'/(.+)\n\n/s'

Я полагаю, что "s" означает одну строку.

 0
Author: ziya, 2010-02-08 14:35:33

Правка: Эхр, неправильно истолковал вопрос.. "bq." было значительным.

echo preg_replace('/^bq\.(.+?)\n\n/s', '<blockquote>$1</blockquote>', $str, 1);

Иногда данные, вводимые через веб-формы, содержат \r\n вместо просто \n, что сделало бы его

echo preg_replace('/^bq\.(.+?)\r\n\r\n/s', '<blockquote>$1</blockquote>', $str, 1);

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

 0
Author: MSpreij, 2010-02-08 14:44:33

Мои инстинкты подсказывают мне что-то вроде...

preg_match("/^bq\. (.+?)\n\n/s", $input, $matches)

Точно так же, как говорит вышеприведенный парень, флаг s после / в конце регулярного выражения означает, что . будет соответствовать символам новой строки. Обычно без этого регулярные выражения представляют собой что-то вроде одной строки.

Затем знак вопроса ? после .+ обозначает не жадное совпадение, так что .+ не будет соответствовать, как может; вместо этого он будет соответствовать минимально возможному, так что \n\n будет соответствовать первому доступному двойному линия.

В какой степени вы планируете поддерживать функции текстиля? Потому что ваше регулярное выражение может стать довольно сложным, так как текстиль допускает такие вещи, как...

bq.. This is a block quote

This is still a block quote

Или...

bq(funky). This is a block quote belonging to the class funky!

bq{color:red;}. Block quote with red text!

Все это, как мне кажется, не сможет обработать ваша техника замены регулярных выражений.

 0
Author: Richard JP Le Guen, 2010-02-08 14:49:02