Convertir la etiqueta de cierre de PHP en comentario


Una de las líneas de mi script contiene una etiqueta de cierre PHP dentro de una cadena. Bajo operación normal esto no causa un problema, pero necesito comentar la línea.

He tratado de comentar esta línea con //, /* */ y # pero ninguno de ellos funciona, el analizador considera que la etiqueta de cierre es una etiqueta de cierre real.

Aquí está la línea en cuestión:

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

¿Qué puedo hacer para comentar la línea anterior?

Author: Alan Moore, 2013-03-05

6 answers

Usa un truco: concatena la cadena de dos piezas. De esta manera, la etiqueta de cierre se corta en dos, y ya no es una etiqueta de cierre válida. '?>' --> '?'.'>'

En su código:

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

Esto hará que los comentarios // funcionen.

Para que los comentarios de /* */ funcionen, también tendrías que dividir la secuencia de */:

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

Recuerde, a veces, a pesar de que el todo es más que la suma de sus partes - pero ser codicioso es malo, hay veces que es mejor quedarse con menos. :)

 124
Author: ppeterka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-07 08:51:48

La forma más fácil

Cree una variable separada para contener su expresión regular; de esta manera simplemente puede comentar la instrucción preg_replace():

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

Arreglo usando clases de caracteres

Para corregir los comentarios de línea, puede dividir ?> poniendo > dentro de una clase de caracteres como así:

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

Para corregir los comentarios de bloque, puede aplicarlo a /:

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

Para corregir ambos estilos de comentario, puede poner / y > en su propia clase de carácter.

Arreglo usando el modificador /x

El x modifier - aka PCRE_EXTENDED - ignora espacios y nuevas líneas en una expresión regular (excepto cuando ocurren dentro de una clase de carácter); esto hace posible agregar espacios para separar los caracteres problemáticos. Para arreglar ambos estilos de comentario:

$string = preg_replace('#<br\s* /? >(?:\s*<br\s* /? >)+#ix', '<br />', $string);
                               ^  ^             ^  ^
 73
Author: Ja͢ck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-24 06:15:34

Por qué tus intentos no funcionaron:

// $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

Lo que funciona:

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

Más lejos...

Después de lo anterior, deberías poder usar /* para comentar la línea. Si dejas el ?> intacto, // no es posible comentar una línea completa. El texto que sigue a ?> podría ser html, que está fuera del control del intérprete PHP, por lo que eso no funcionaría.

De la documentación:

Los estilos de comentario de "una línea" solo comentan al final de la línea o el bloque actual de código PHP, lo que ocurra primero. Esto significa que Código HTML después de//... ?> o # ... ?> SE imprimirá:?> estallidos de modo PHP y vuelve al modo HTML, y / / o # no puede influir que.

 38
Author: Anirudh Ramanathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-05 13:56:31

Otra idea: Escapa del > (y del /, si quieres usar un comentario /*...*/):

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

Un escape "innecesario" es ignorado por el motor de expresiones regulares, pero es útil en este caso (por las razones descritas en las otras respuestas).

 15
Author: Tim Pietzcker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-10 09:15:57

¿Por qué usar "trucos" complicados y difíciles de leer para solucionar el problema?

? es solo un atajo cuantificador para mayor comodidad, así que

Solo tiene que utilizar la versión larga del cuantificador {0,1}, significa "mínimo 0 máximo 1 ocurrencia":

$string = preg_replace('#<br\s*/{0,1}>(?:\s*<br\s*/{0,1}>)+#i', '<br />', $string);
 10
Author: stema,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-08 09:11:23

Algunas otras formas que vale la pena agregar al libro de trucos de expresiones regulares :

Primero puedes compactar tu RegEx a: /(<br\s*/?>)+/i y reemplazarla por <br /> (no es necesario cargar la RegExP con lookaheads) y siempre terminarás con tu salto de línea XHMTL elegido.

Otras formas de modificar su expresión regular para que no se trip */ end comment o ?> end script:

  • Use cuantificadores posesivos : #(<br\s*+/?+>)+#i - lo que básicamente significa para \s*+ si encontró que los espacios en blanco coinciden como muchos como hay y guardarlo, y para /?+ si usted encontró una barra guardarlo!
  • Encierran \s* y /* en grupos de captura = > #(<br(\s*)(/?)>)+#i

Demos en vivo: http://codepad.viper-7.com/YjqUbi

Y desde que nos inclinamos por el comportamiento posesivo la expresión regular más rápida que también pasa por alto el problema de los comentarios es: #(<br\s*+/?+>)++#i demostración explicada


En cuanto a comentar en situaciones difíciles

Cuando no se puede cambiar el código, o tener ya se ha utilizado un comentario multilínea y:

1. Use un nowdoc:

    $string='Hello<br>World<br><br />World<br><br><br>Word!';
    <<<'comment'
    $string = preg_replace('#(<br\s*/?>)+#i', '<br />', $string);
comment;

Código vivo: http://codepad.viper-7.com/22uOtV

Nota: un nowdoc {[41] } es similar a un heredoc pero no analiza el contenido y tiene que tener su comenzando delimitador encerrado entre 'comillas simples' (tenga en cuenta que el delimitador final no se puede identificar , debe ir seguido de ; y una nueva línea !)

2. Saltar sobre el código con un goto:

$string='Hello<br>World<br><br />World<br><br><br>Word!';
goto landing;
$string = preg_replace('#(<br\s*/?>)+#i', '<br />', $string);
landing:

Ejemplo en vivo: http://codepad.viper-7.com/UfqrIQ

3. Saltar sobre el código con if(false) o if(0):

$string='Hello<br>World<br><br />World<br><br><br>Word!';
if(0){
$string = preg_replace('#(<br\s*/?>)+#i', '<br />', $string);
}

Prueba: http://codepad.viper-7.com/wDg5H5

 8
Author: CSᵠ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-11 13:39:46