Я делаю простой синтаксический анализатор Textile и пытаюсь написать регулярное выражение для «blockquote», но мне трудно сопоставить несколько новых строк. Пример:
Бк. первая строка цитаты вторая строка цитаты третья строка цитаты не часть цитаты
Он будет заменен тегами preg_replace()
с помощью preg_replace()
поэтому в основном ему нужно preg_replace()
все между "bq."
и первая двойная новая линия, с которой она сталкивается. Лучшее, что я могу сделать, это получить первую строку цитаты. благодаря
Попробуйте это регулярное выражение:
(?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 и (newer) MacOS. Если вам нужно учитывать реальные старые компьютеры Mac, добавьте сингл \r
к нему: \r?\n|\r
Этот принятый ответ захватил только последний символ блока. В итоге я использовал это:
$text =~ /(?s)bq\.(.+?)\n\n/g
Будет ли это работать?
'/(.+)\n\n/s'
Я считаю, что это означает «одна линия».
Изменить: Ehr, неправильно спросите вопрос .. "bq." был значительным.
echo preg_replace('/^bq\.(.+?)\n\n/s', '<blockquote>$1</blockquote>', $str, 1);
Иногда данные, вводимые через webforms, содержат \ 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
после /
в конце RegEx означает, что .
будет соответствовать новым строковым символам. Обычно, без этого, RegEx являются своего рода одной строкой.
Тогда вопросительный знак ?
после символа .+
означает не-жадное совпадение, так что .+
не будет соответствовать, как может; вместо этого он будет соответствовать минимально возможному, так что \n\n
будет соответствовать первой доступной двойной строке.
В какой мере вы планируете поддерживать функции Textile? Поскольку ваш RegEx может стать довольно сложным, поскольку Textile позволяет такие вещи, как …
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!
Все, с чем ваша техника с заменой регулярного выражения не сможет справиться, говорит.