Регулярное выражение для сопоставления блока текста с первой двойной новой строкой?
Я создаю простой синтаксический анализатор текстиля и пытаюсь написать регулярное выражение для "blockquote", но у меня возникают трудности с сопоставлением нескольких новых строк. Пример:
bq. first line of quote second line of quote third line of quote not part of the quote
Он будет заменен тегами blockquote через preg_replace()
, поэтому в основном он должен соответствовать всему, что находится между "bq."
и первой двойной новой строкой, с которой он сталкивается. Лучшее, что я могу сделать, - это получить первую строку цитаты. Спасибо
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
Этот принятый ответ захватил для меня только последний символ блока. В итоге я использовал это:
$text =~ /(?s)bq\.(.+?)\n\n/g
Сработает ли это?
'/(.+)\n\n/s'
Я полагаю, что "s" означает одну строку.
Правка: Эхр, неправильно истолковал вопрос.. "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);
Вопросительный знак заставляет его добавлять закрывающие кавычки после первого найденного двойного возврата ("не жадный", как я полагаю, это называется), поэтому любые другие двойные возвраты остаются в покое (если это не то, что вы хотите, очевидно, уберите это).
Мои инстинкты подсказывают мне что-то вроде...
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!
Все это, как мне кажется, не сможет обработать ваша техника замены регулярных выражений.