Преобразование закрывающего тега PHP в комментарий
Одна из строк в моем script содержит закрывающий тег PHP внутри строки. При нормальной работе это не вызывает проблемы, но мне нужно прокомментировать строку.
Я попытался прокомментировать эту строку с //
, /*
*/
и #
, но ни один из них не работает, парсер считает закрывающий тег фактическим закрывающим тегом.
Вот строка, о которой идет речь:
$string = preg_replace('#<br\s*/?>(?:\s*<br\s*/?>)+#i', '<br />', $string);
// ^^ ^^
Что я могу сделать, чтобы прокомментировать указанную выше строку?
Ответы
Ответ 1
Используйте трюк: объедините строку из двух частей. Таким образом, закрывающий тег разрезается на два и больше не является допустимым закрывающим тегом. '?>' --> '?'.'>'
В вашем коде:
$string = preg_replace('#<br\s*/?'.'>(?:\s*<br\s*/?'.'>)+#i', '<br />', $string);
Это сделает комментарии //
.
Для комментариев /* */
для работы вам также потребуется разбить последовательность */
:
$string = preg_replace('#<br\s*'.'/?'.'>(?:\s*<br\s*'.'/?'.'>)+#i', '<br />', $string);
Помните, иногда, хотя целое больше, чем сумма его частей - но быть жадным - это плохо, есть времена, когда вам лучше оставить меньше.:)
Ответ 2
Самый простой способ
Создайте отдельную переменную, чтобы сохранить регулярное выражение; таким образом вы можете просто прокомментировать инструкцию 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
modifier - aka PCRE_EXTENDED
- игнорирует пробелы и символы новой строки в регулярном выражении (за исключением случаев, когда они встречаются внутри класс символов); это позволяет добавлять пробелы для разделения проблемных символов. Чтобы исправить оба стиля комментариев:
$string = preg_replace('#<br\s* /? >(?:\s*<br\s* /? >)+#ix', '<br />', $string);
^ ^ ^ ^
Ответ 3
Почему ваши попытки не сработали:
// $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, а//или # не могут влиять что.
Ответ 4
Другая идея: Escape >
(и /
, если вы хотите использовать комментарий /*...*/
):
$string = preg_replace('#<br\s*\/?\>(?:\s*<br\s*\/?\>)+#i', '<br />', $string);
"ненужный" escape игнорируется движком регулярных выражений, но полезен в этом случае (по причинам, изложенным в других ответах).
Ответ 5
Зачем использовать сложные, трудночитаемые "трюки" для решения этой проблемы?
?
- это просто ярлык квантификатора для удобства, поэтому
Просто используйте длинную версию квантификатора {0,1}
, значит "минимум 0 максимум 1 вхождение":
$string = preg_replace('#<br\s*/{0,1}>(?:\s*<br\s*/{0,1}>)+#i', '<br />', $string);
Ответ 6
Несколько других способов добавить в книгу трюков RegEx:
Сначала вы можете сжать свой RegEx до: /(<br\s*/?>)+/i
и заменить на <br />
(нет необходимости обременять RegExP с помощью lookaheads), и вы всегда будете в конечном итоге с выбранным вами перерывом строки XHMTL.
Другие способы изменения вашего RegEx, чтобы он не отключил окончательный комментарий */
или ?>
end script:
- Используйте притяжательные квантификаторы:
#(<br\s*+/?+>)+#i
- которые в основном означают для \s*+
, если вы нашли пробельные совпадения столько, сколько их есть и сохраните, а для /?+
если вы нашли косую черту!
- Включить
\s*
и /*
в группы захвата = > #(<br(\s*)(/?)>)+#i
Живые демонстрации: http://codepad.viper-7.com/YjqUbi
И так как мы склонялись к притяжательному поведению, самый быстрый RegEx, который также обходит проблему комментариев: #(<br\s*+/?+>)++#i
объяснил демо
Что касается комментирования в сложных ситуациях
Если вы не можете изменить код или уже использовали многострочный комментарий и:
1. Используйте nowdoc:
$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
Примечание: a nowdoc похож на heredoc, но он не анализирует содержимое и должен иметь его начальный разделитель, заключенный в '
одинарные кавычки '
(обратите внимание, что окончательный разделитель не может быть идентифицирован, за ним следует ;
и новая строка!)
2. Перепрыгните через код с помощью goto:
$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);
}
Тест: http://codepad.viper-7.com/wDg5H5