Помогите с регулярным выражением, которое убирает ведущие пробелы - PullRequest
1 голос
/ 09 августа 2009

Я изменяю основную функцию библиотеки Кохана, функцию text :: auto_p () .

Функция описывает себя как "nl2br () на стероидах". По сути, он обеспечивает <br /> разрывы строк, но двойные разрывы строк заключены в теги <p>.

Ограничение, которое я обнаружил, заключается в том, что оно будет <br /> s в элементе <pre>. Это создаст двойные новые строки, а это не то, что я хочу. Я сделал модификацию, чтобы подобрать предварительные элементы с помощью регулярного выражения и обратного вызова, который удалит <br />, который работает нормально.

Однако основная проблема заключается в том, что в моем тексте есть примеры кода, которые получают auto_p() 'd, и мне нужно сохранить отступ (для удобства чтения). К сожалению для меня, функция убирает начальные и конечные пробелы в строках.

Вот регулярное выражение, которое удаляет начальное пространство

$str = preg_replace('~^[ \t]+~m', '', $str);

Я не лучший гуру регулярных выражений, но я вполне уверен, что он говорит: «Получите начальные пробелы и табуляции там, где есть хотя бы одна, и замените их пустой строкой».

Я попытался удалить эту строку, но затем она добавит <br /> там, где я определенно не хочу их - в одном случае я получаю вывод, подобный этому

<ul><br />
    <li>something</li>
</ul>

Как бы я изменил это регулярное выражение или код, чтобы не убирать начальный пробел внутри элемента <pre>?

Оригинальная вспомогательная функция от Kohana доступна здесь . (прокрутите к почти дну).

Я знаю, что получу несколько ответов типа «Использовать HTML-парсер» - и хотя вы можете быть правы - существующий код просто использует регулярное выражение, и я бы предпочел более простое решение (где мне не нужно включать библиотека и т. д.).

Спасибо за ваше время.

Ответы [ 2 ]

1 голос
/ 09 августа 2009

Вот как бы я это сделал:

$str = preg_replace(
    '~^[ \t]++(?=(?:[^<]++|<(?!/?+pre\b))*+(?:\z|<pre\b))~im',
    '', $str);

После сопоставления с пробелами, начинающимися со строки, заглядывающий вперед сканирует теги <pre> или </pre>. Мясо предвкушения - это немного:

(?:[^<]++|<(?!/?+pre\b))*+

Соответствует нулю или большему количеству всего, что не является левой угловой скобкой, или левой угловой скобкой, если это не начало тега <pre> или </pre>. Эта часть прекратит сопоставление, только когда встретит тег <pre> (начальный), тег </pre> (конечный) или конец ввода. Если это конечный тег, который останавливает его, вы знаете, что находитесь внутри элемента <PRE>, поэтому вы не хотите выполнять замену.

Притяжательные квантификаторы ('++', '*+' и '?+') необходимы для предотвращения катастрофического возврата . (Я не могу с этим поделать: эта фраза всегда заставляет меня вспомнить сценарий резонансного каскада из Half-Life .)

Этот метод также предполагает разумно правильно сформированный HTML, т. Е. Все теги ... должным образом сбалансированы. Теги внутри комментариев SGML также могут испортить это, если они не будут сбалансированы. Вы также можете иметь дело с комментариями, если вы не против сделать регулярное выражение в два раза длиннее и в три раза уродливее. :)

0 голосов
/ 09 августа 2009

Я думаю, что ваша проблема обсуждается много раз - перейдите по этой ссылке

http://us3.php.net/manual/en/function.nl2br.php#91828

Это тоже:

http://us3.php.net/manual/en/function.nl2br.php#39641

...