Преобразовать закрывающий тег PHP в комментарий
Одна из строк в моем скрипте содержит закрывающий тег PHP внутри строки. При нормальной работе это не вызывает проблем, но мне нужно прокомментировать строку.
Я попытался прокомментировать эту строку с помощью //
, /*
*/
и #
но ни один из них не работает, синтаксический анализатор считает закрывающий тег фактическим закрывающим тегом.
Вот строка, о которой идет речь:
$string = preg_replace('#<br\s*/?>(?:\s*<br\s*/?>)+#i', '<br />', $string);
// ^^ ^^
Что я могу сделать, чтобы прокомментировать приведенную выше строку?
6 answers
Используйте трюк: соедините строку из двух частей. Таким образом, закрывающий тег разрезается надвое и больше не является допустимым закрывающим тегом. '?>' --> '?'.'>'
В вашем коде:
$string = preg_replace('#<br\s*/?'.'>(?:\s*<br\s*/?'.'>)+#i', '<br />', $string);
Это заставит //
комментарии работать.
Чтобы комментарии /* */
работали, вам также придется разделить последовательность */
:
$string = preg_replace('#<br\s*'.'/?'.'>(?:\s*<br\s*'.'/?'.'>)+#i', '<br />', $string);
Помните, иногда, даже если целое больше, чем сумма его частей - но быть жадным плохо, бывают моменты, когда вам лучше остаться с меньше. :)
Самый простой способ
Создайте отдельную переменную для хранения вашего регулярного выражения; таким образом, вы можете просто закомментировать оператор preg_replace()
:
$re = '#<br\s*/?>(?:\s*<br\s*/?>)+#i';
// $string = preg_replace($re, '<br />', $string);
Исправлено использование классов символов
Чтобы исправить комментарии к строкам, вы можете разбить ?>
, поместив >
внутри класса символов следующим образом:
$string = preg_replace('#<br\s*/?[>](?:\s*<br\s*/?[>])+#i', '<br />', $string);
^ ^ ^ ^
Чтобы исправить комментарии блока, вы можете применить его к /
:
$string = preg_replace('#<br\s*[/]?>(?:\s*<br\s*[/]?>)+#i', '<br />', $string);
^ ^ ^ ^
Чтобы исправить оба стиля комментариев, вы можете поместить /
и >
в их собственном классе персонажей.
Исправлено использование модификатора /x
В x
модификатор - он же PCRE_EXTENDED
- игнорирует пробелы и новые строки в регулярном выражении (за исключением случаев, когда они встречаются внутри класса символов); это позволяет добавлять пробелы для разделения проблемных символов. Чтобы исправить оба стиля комментариев:
$string = preg_replace('#<br\s* /? >(?:\s*<br\s* /? >)+#ix', '<br />', $string);
^ ^ ^ ^
Почему ваши попытки не сработали:
// $string = preg_replace('#<br\s*/?>(?:\s*<br\s*/?>)+#i',...
^ doesn't work due to ?> ending php
/* $string = preg_replace('#<br\s*/?>(?:\s*<br\s*/?>)+#i',... */
^ doesn't work due to */ closing comment
Что работает:
/* $string = preg_replace('#<br\s*[/]?>(?:\s*<br\s*[/]?>)+#i',... */
^ ^ ^ ^
// $string = preg_replace('#<br\s*/?[>](?:\s*<br\s*/?[>])+#i',...
^ ^ ^ ^
Дальше...
После вышесказанного вы должны иметь возможность использовать /*
для закомментирования строки.
Если вы оставите ?>
нетронутым, //
не сможет прокомментировать всю строку. Текст, следующий за ?>
, может быть html, который находится вне контроля интерпретатора PHP, так что это не сработает.
Стили комментариев "однострочный" комментируют только конец строки или текущий блок кода PHP, в зависимости от того, что наступит раньше. Это означает, что HTML-код после // ...?> или #...?> БУДЕТ напечатан: ?> выходит из режима PHP и возвращается в режим HTML, и //или # не может повлиять это.
Еще одна идея: Избежать >
(и /
, если вы хотите использовать комментарий /*...*/
):
$string = preg_replace('#<br\s*\/?\>(?:\s*<br\s*\/?\>)+#i', '<br />', $string);
"Ненужный" побег игнорируется механизмом регулярных выражений, но в данном случае полезен (по причинам, изложенным в других ответах).
Зачем использовать сложные, трудночитаемые "уловки" для решения проблемы?
?
это просто ярлык квантора для удобства, поэтому
Просто используйте длинную версию квантора {0,1}
, означает "минимум 0 максимум 1 случай":
$string = preg_replace('#<br\s*/{0,1}>(?:\s*<br\s*/{0,1}>)+#i', '<br />', $string);
Несколько других способов, которые стоит добавить в книгу трюков с регулярными выражениями :
Сначала вы можете сжать свое регулярное выражение до: /(<br\s*/?>)+/i
и заменить на <br />
(не нужно нагружать регулярное выражение ссылками), и вы всегда будете иметь выбранный разрыв строки XHMTL.
Другие способы изменить регулярное выражение, чтобы оно не срабатывало */
завершающий комментарий или ?>
завершающий сценарий:
- Используйте притяжательные кванторы :
#(<br\s*+/?+>)+#i
- что в основном означает для\s*+
, если вы нашли пробелы сопоставьте столько, сколько есть, и сохраните его, а для/?+
, если вы нашли косую черту, сохраните ее! - Заключить
\s*
и/*
в группы захвата =>#(<br(\s*)(/?)>)+#i
Живые демо-версии: http://codepad.viper-7.com/YjqUbi
И поскольку мы склонялись к собственническому поведению, самым быстрым регулярным выражением, которое также обходит проблему с комментариями, является: #(<br\s*+/?+>)++#i
объясненная демонстрация
Что касается комментариев в сложных ситуациях
Когда вы не можете изменить код, или уже использовали многострочный комментарий и:
1. Используйте теперь я:
$string='Hello<br>World<br><br />World<br><br><br>Word!';
<<<'comment'
$string = preg_replace('#(<br\s*/?>)+#i', '<br />', $string);
comment;
Оперативный код: http://codepad.viper-7.com/22uOtV
Примечание: nowdoc похож на heredoc, но он не анализирует содержимое и должен содержать начальный разделитель, заключенный в '
одинарные кавычки'
( обратите внимание, что конечный разделитель не может быть идентифицирован , за ним должны следовать ;
и новая строка !)
2. Перепрыгните через код с помощью перехода:
$string='Hello<br>World<br><br />World<br><br><br>Word!';
goto landing;
$string = preg_replace('#(<br\s*/?>)+#i', '<br />', $string);
landing:
Живой пример: http://codepad.viper-7.com/UfqrIQ
3. Перепрыгните через код с помощью if(false)
или if(0)
:
$string='Hello<br>World<br><br />World<br><br><br>Word!';
if(0){
$string = preg_replace('#(<br\s*/?>)+#i', '<br />', $string);
}