Compilar expresiones regulares en PHP

4 minutos de lectura

¿Hay alguna forma en PHP de compilar una expresión regular, de modo que luego pueda compararse con varias cadenas sin repetir el proceso de compilación? Otros lenguajes importantes pueden hacer esto: Java, C#, Python, Javascript, etc.

Es posible que la biblioteca de expresiones regulares compatibles con Perl ya esté optimizada para su caso de uso sin proporcionar una clase Regex como lo hacen otros lenguajes:

Esta extensión mantiene una memoria caché global por subproceso de expresiones regulares compiladas (hasta 4096).

PCRE Introducción

Así es como el modificador de estudio que describió Imran puede almacenar la expresión compilada entre llamadas.

  • ¿Puedo aumentar el tamaño de la caché por subproceso y cuál es el significado de 4096?

    – sagar junnarkar

    11 de septiembre de 2013 a las 5:07

  • Creo que significa 4096 expresiones regulares compiladas.

    – Tobía

    28 de septiembre de 2016 a las 14:16

Las expresiones regulares preg pueden usar el modificador S (estudio) en mayúsculas, que es probablemente lo que está buscando.

http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php

S

Cuando un patrón se va a usar varias veces, vale la pena dedicar más tiempo a analizarlo para acelerar el tiempo de coincidencia. Si se establece este modificador, se realiza este análisis adicional. En la actualidad, estudiar un patrón es útil solo para patrones no anclados que no tienen un solo carácter de inicio fijo.

  • La respuesta a la pregunta del OP es que no hay necesidad de compilar previamente las expresiones regulares en PHP porque, como señaló 1stvamp, las expresiones regulares compiladas se almacenan en caché automáticamente. El modificador ‘S’ es un tema aparte.

    –Alan Moore

    7 de abril de 2009 a las 3:39

  • Esta respuesta se ha agregado a las Preguntas frecuentes sobre expresiones regulares de desbordamiento de pila, en “Modificadores”.

    – una mente literal

    10 de abril de 2014 a las 0:41

El subproceso es el subproceso en el que se ejecuta actualmente el script. Después del primer uso, la expresión regular compilada se almacena en caché y la próxima vez que se usa, PHP no la vuelve a compilar.

Prueba sencilla:

<?php

function microtime_float() {
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

// test string
$text="The big brown <b>fox</b> jumped over a lazy <b>cat</b>";
$testTimes=10;


$avg=0;
for ($x=0; $x<$testTimes; $x++)
{
    $start=microtime_float();
    for ($i=0; $i<10000; $i++) {
        preg_match_all('/<b>(.*)<\/b>0?/', $text, $m);
    }
    $end=microtime_float();
    $avg += (float)$end-$start;
}

echo 'Regexp with caching avg '.($avg/$testTimes);

// regexp without caching
$avg=0;
for ($x=0; $x<$testTimes; $x++)
{
    $start=microtime_float();
    for ($i=0; $i<10000; $i++) {
        $pattern='/<b>(.*)<\/b>'.$i.'?/';
        preg_match_all($pattern, $text, $m);
    }
    $end=microtime_float();
    $avg += (float)$end-$start;
}

echo '<br/>Regexp without caching avg '.($avg/$testTimes);

Regexp con almacenamiento en caché avg 0.1 Regexp sin almacenamiento en caché avg 0.8

¡El almacenamiento en caché de una expresión regular lo hace 8 veces más rápido!

  • La prueba es NUL! Porque: está concatenando 3 cadenas en su segundo ejemplo (sin almacenamiento en caché) mientras que en el primero la ‘variable’ $i no existe en el patrón y siempre es 0 en ese lugar

    – CSᵠ

    8 de noviembre de 2014 a las 3:38


  • la prueba es razonablemente válido sin embargo. Al concatenar una cadena “$j-$y” con $j = 37 y $y = 5 en la primera prueba, y una cadena “$i-$x” en la segunda (el -$x es para anular cualquier almacenamiento en caché por testTimes), obtengo tiempos de 0.0112 y 0.0431. El mismo 0.0431 se obtiene al usar “$i-$y” en la segunda prueba, lo que significa que, de hecho, el caché tiene un tamaño inferior a 10000. Mi aceleración real es así 4 veces más rápido (no 8).

    – LSerni

    29 de octubre de 2015 a las 8:44

Como ya dijo otro comentarista, las expresiones regulares de PCRE ya están compiladas sin que tenga que hacer referencia a ellas específicamente como tales, PCRE mantiene un hash interno indexado por la cadena original que proporcionó.

avatar de usuario
EBVerde

No estoy seguro de que puedas. Si revisa Dominar expresiones regulares, algunas técnicas de optimización específicas de PHP se analizan en el Capítulo 10: PHP. Específicamente, el uso del modificador de patrón S para hacer que el motor de expresiones regulares “estudie” la expresión regular antes de aplicarla. Dependiendo de su patrón y su texto, esto podría brindarle algunas mejoras de velocidad.

Editar: puedes echar un vistazo al contenido del libro usando libros.google.com.

  • ¡Todo desarrollador que use expresiones regulares debería leer este libro! Todas las técnicas que necesitas para ser eficiente están en este libro.

    – Arno

    8 de diciembre de 2009 a las 14:35

  • ¡Todo desarrollador que use expresiones regulares debería leer este libro! Todas las técnicas que necesitas para ser eficiente están en este libro.

    – Arno

    8 de diciembre de 2009 a las 14:35

¿Ha sido útil esta solución?