Регулярное выражение для соответствия блока текста до первой двойной новой строки? - PullRequest
4 голосов
/ 08 февраля 2010

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

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

not part of the quote

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

Ответы [ 5 ]

6 голосов
/ 08 февраля 2010

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

(?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

1 голос
/ 12 ноября 2015

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

$text =~ /(?s)bq\.(.+?)\n\n/g
0 голосов
/ 08 февраля 2010

Мои инстинкты говорят мне что-то вроде ...

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

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

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

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

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 голосов
/ 08 февраля 2010

Edit: Ehr, неправильно прочитал вопрос .. "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 голосов
/ 08 февраля 2010

Будет ли это работать?

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

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

...