¿Existe una función PHP que pueda escapar de los patrones de expresiones regulares antes de que se apliquen?

161

¿Existe una función PHP que pueda escapar de los patrones de expresiones regulares antes de que se apliquen?

Estoy buscando algo en la línea de la Regex.Escape()función C # .

vfclists
fuente

Respuestas:

254

preg_quote() es lo que buscas:

Descripción

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

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

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

Parámetros

str

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 destacar que si $delimiterno 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é utilizando con su expresión regular como $delimiterargumento.

Ejemplo: usar preg_matchpara buscar ocurrencias de una URL determinada rodeada de 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 '/' as the
// $delimiter argument).
$escapedUrl = preg_quote($url, '/');

// We enclose our regex in '/' 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 "
// }
Tom Haigh
fuente
11
Una observación adicional a la respuesta de @TomHaigh , si no especifica el segundo $delimiterargumento preg_quote() , no escapará a ningún delimitador , ni siquiera al "predeterminado" (o el más común) /.
Alix Axel
He agregado un montón de cosas a esta respuesta: la nota presentada por @AlixAxel sobre la importancia del $delimiterargumento, la descripción de ese argumento de los documentos, una aclaración para los confundidos sobre exactamente lo que significa, y un gran ejemplo comentado que muestra el preg_quoteuso en el caso más simple que se me ocurre cuando realmente 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
1

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

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

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

luego realice una coincidencia t-regx normal :

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

$matches = $pattern->match($haystack)->all();
Danon
fuente