Преобразовать закрывающий тег PHP в комментарий


Одна из строк в моем скрипте содержит закрывающий тег PHP внутри строки. При нормальной работе это не вызывает проблем, но мне нужно прокомментировать строку.

Я попытался прокомментировать эту строку с помощью //, /* */ и # но ни один из них не работает, синтаксический анализатор считает закрывающий тег фактическим закрывающим тегом.

Вот строка, о которой идет речь:

$string = preg_replace('#<br\s*/?>(?:\s*<br\s*/?>)+#i', '<br />', $string);
//                              ^^             ^^

Что я могу сделать, чтобы прокомментировать приведенную выше строку?

Author: Alan Moore, 2013-03-05

6 answers

Используйте трюк: соедините строку из двух частей. Таким образом, закрывающий тег разрезается надвое и больше не является допустимым закрывающим тегом. '?>' --> '?'.'>'

В вашем коде:

$string = preg_replace('#<br\s*/?'.'>(?:\s*<br\s*/?'.'>)+#i', '<br />', $string);

Это заставит // комментарии работать.

Чтобы комментарии /* */ работали, вам также придется разделить последовательность */:

$string = preg_replace('#<br\s*'.'/?'.'>(?:\s*<br\s*'.'/?'.'>)+#i', '<br />', $string);

Помните, иногда, даже если целое больше, чем сумма его частей - но быть жадным плохо, бывают моменты, когда вам лучше остаться с меньше. :)

 124
Author: ppeterka, 2013-03-07 08:51:48

Самый простой способ

Создайте отдельную переменную для хранения вашего регулярного выражения; таким образом, вы можете просто закомментировать оператор 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);
                               ^  ^             ^  ^
 73
Author: Ja͢ck, 2013-04-24 06:15:34

Почему ваши попытки не сработали:

// $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, и //или # не может повлиять это.

 38
Author: Anirudh Ramanathan, 2013-03-05 13:56:31

Еще одна идея: Избежать >/, если вы хотите использовать комментарий /*...*/):

$string = preg_replace('#<br\s*\/?\>(?:\s*<br\s*\/?\>)+#i', '<br />', $string);

"Ненужный" побег игнорируется механизмом регулярных выражений, но в данном случае полезен (по причинам, изложенным в других ответах).

 15
Author: Tim Pietzcker, 2013-04-10 09:15:57

Зачем использовать сложные, трудночитаемые "уловки" для решения проблемы?

? это просто ярлык квантора для удобства, поэтому

Просто используйте длинную версию квантора {0,1}, означает "минимум 0 максимум 1 случай":

$string = preg_replace('#<br\s*/{0,1}>(?:\s*<br\s*/{0,1}>)+#i', '<br />', $string);
 10
Author: stema, 2013-03-08 09:11:23

Несколько других способов, которые стоит добавить в книгу трюков с регулярными выражениями :

Сначала вы можете сжать свое регулярное выражение до: /(<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);
}

Тест: http://codepad.viper-7.com/wDg5H5

 8
Author: CSᵠ, 2013-04-11 13:39:46