PHP: ¿Escape el patrón RegEx para evitar que se aplique?

4 minutos de lectura

avatar de usuario de vfclists
vfclists

¿Existe una función PHP que pueda escapar de los patrones RegEx para evitar que se apliquen cuando se usan dentro de otro patrón RegEx?

Estoy buscando algo a lo largo de las líneas de C # Regex.Escape() función.

Avatar de usuario de Tom Haigh
tom haigh

preg_quote() es lo que buscas:

Descripción

string preg_quote ( string $str [, string $delimiter = NULL ] )

preg_quote() acepta str y coloca una barra invertida delante de cada carácter que forma parte de la sintaxis de la expresión regular. Esto es útil si tiene una cadena en tiempo de ejecución que necesita hacer coincidir en algún texto y la cadena puede contener caracteres especiales de expresión regular.

Los caracteres especiales de expresión regular son: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : -

Parámetros

calle

La cadena de entrada.

delimitador

Si se especifica el delimitador opcional, también se escapará. Esto es útil para escapar del delimitador que requieren las funciones PCRE. El / es el delimitador más utilizado.

Es importante señalar que si el $delimiter no se especifica el argumento, el delimitador – el carácter utilizado para encerrar su expresión regular, comúnmente una barra diagonal (/) – no se escapará. Por lo general, querrá pasar cualquier delimitador que esté usando con su expresión regular como el $delimiter argumento.

Ejemplo – usando preg_match para encontrar ocurrencias de una URL dada rodeada por espacios en blanco:

$url="http://stackoverflow.com/questions?sort=newest";

// preg_quote escapes the dot, question mark and equals sign in the URL (by
// default) as well as all the forward slashes (because we pass "https://stackoverflow.com/" as the
// $delimiter argument).
$escapedUrl = preg_quote($url, "https://stackoverflow.com/");

// We enclose our regex in "https://stackoverflow.com/" characters here - the same delimiter we passed
// to preg_quote
$regex = '/\s' . $escapedUrl . '\s/';
// $regex is now:  /\shttp\:\/\/stackoverflow\.com\/questions\?sort\=newest\s/

$haystack = "Bla bla http://stackoverflow.com/questions?sort=newest bla bla";
preg_match($regex, $haystack, $matches);

var_dump($matches);
// array(1) {
//   [0]=>
//   string(48) " http://stackoverflow.com/questions?sort=newest "
// }

  • Un comentario adicional a la respuesta de @TomHaigh, si no especifica el segundo $delimiter argumento a preg_quote() no escapará a ningún delimitadorni siquiera el “predeterminado” (o el más común) /.

    – Alix Axel

    20 de junio de 2012 a las 3:39


  • He agregado un montón de cosas a esta respuesta: la nota presentada por @AlixAxel sobre la importancia de la $delimiter argumento, la descripción de ese argumento de los documentos, una aclaración para los confundidos acerca de lo que significa exactamente, y un ejemplo muy comentado que muestra preg_quote se usa en el caso más simple que se me ocurrió donde en realidad se usa para formar programáticamente una expresión regular y ponerla en otra preg_* función (porque de lo contrario, ¿cuál es el punto?). Siéntase libre de retroceder si no le gusta el cambio.

    –Mark Amery

    21 de septiembre de 2015 a las 23:04

  • @AlixAxel La función preg_quote() escapa a algunos delimitadores, incluidos =: . Ver mi artículo: abareplace.com/blog/escape-regexp

    -Peter Kankowski

    8 de enero de 2022 a las 11:41


Avatar de usuario de Danon
Danón

Sería mucho más seguro de usar Patrones preparados de Regx T:

$url="http://stackoverflow.com/questions?sort=newest";

$pattern = Pattern::inject('\s@\s', [$url]);
                                    // ↑ $url is quoted

luego realiza una coincidencia normal:

$haystack = "Bla bla http://stackoverflow.com/questions?sort=newest bla bla";

$matcher = pattern->match($haystack);
foreach ($matcher as $match) {
}

Incluso puedes usarlo con preg_match():

preg_match($pattern, 'foo', $matches);

  • ¿Puede explicar por qué debería ser “más seguro” extraer otra biblioteca, si un PHP estándar hace el trabajo?

    – Adrián

    18 de enero de 2022 a las 7:38

  • Vanilla PHP no funciona en todos los casos. Por ejemplo cadena "\\" causará un error si es el último carácter.

    – Danón

    24 de enero de 2022 a las 13:07

  • Esta es la segunda respuesta tuya que veo en un día mencionando esta biblioteca, y ahora me doy cuenta de que es porque es tuya. La política de SO requiere que aclare cualquier asociación en su respuesta cuando recomiende sus propias herramientas.

    – Hashim Aziz

    21 de marzo a las 19:02

  • @HashimAziz Gracias por avisar, publiqué la respuesta hace 4 años justo después de crear la lib. Fui joven y tonto, acepta mis disculpas.

    – Danón

    22 de marzo a las 8:22

¿Ha sido útil esta solución?