regulares probar preg_replace preg_match_all preg_match lista expresiones especiales caracteres php regex string performance

php - preg_replace - probar expresiones regulares



¿Qué es más eficiente, funciones de cadena de PHP o expresiones regulares en PHP? (9)

Estoy escribiendo código PHP para analizar una cadena. Debe ser lo más rápido posible, ¿son las expresiones regulares el camino a seguir? Tengo el presentimiento de que las funciones de cadena de PHP son más caras, pero es solo una suposición. ¿Cuál es la verdad?

Aquí está específicamente lo que necesito hacer con la cadena:

Coge la primera mitad (basada en la tercera ubicación de una subcadena "000000") y compara su hash con los siguientes 20 bytes, tirando todo lo que quede.

Analice el 9º byte a través del siguiente "000000" como una pieza de datos. Luego, tome los siguientes 19 bytes y divídalos en 8 (lanzar 1) y 8. Luego hago otras cosas que convierten esas dos cadenas de 8 bytes en fechas.

Ese es el tipo de cosas que necesito hacer.


Creo que hay un umbral desde el cual una expresión regular es más rápida que un montón de llamadas a funciones de cadena de PHP. De todos modos, depende mucho de lo que estés haciendo. Tienes que encontrar el equilibrio.

Ahora que editaste tu pregunta. Usaría funciones de cadena para lo que estás tratando de lograr. strpos () y substr () es lo que viene a la mente a primera vista.


Creo que si desea obtener el máximo rendimiento, debe evitar las expresiones regulares, ya que ayuda a minimizar el esfuerzo, pero no tendrá el mejor rendimiento, ya que casi siempre puede ajustar el código utilizando rutinas de cadenas para un problema específico y obtener un gran aumento de rendimiento. Pero para rutinas de análisis simples que no se pueden optimizar mucho, todavía puede usar expresiones regulares ya que no habrá una gran diferencia allí.

EDITAR: Para este problema específico que publicaste, favorecería las operaciones de cadena, pero solo porque no sabría cómo hacerlo en expresiones regulares. Esto parece ser bastante sencillo, excepto por el hash, así que creo que las funciones de expresión regular / cadena no harán una gran diferencia.


Depende de su caso: si está tratando de hacer algo bastante básico (por ejemplo: buscar una cadena, reemplazar una subcadena con otra cosa), entonces las funciones de cadena normales son el camino a seguir. Si desea hacer algo más complicado (por ejemplo: buscar direcciones IP), las funciones Regex son definitivamente una mejor opción.

No he perfilado las expresiones regulares por lo que no puedo decir que serán más rápidas en el tiempo de ejecución, pero puedo decir que el tiempo extra dedicado a piratear el equivalente utilizando las funciones básicas no valdría la pena.

Editar con la nueva información en el OP:

Suena como si realmente necesitas hacer una serie de pequeñas operaciones de cadena aquí. Ya que cada uno individualmente es bastante básico, y dudo que puedas hacer todos esos pasos (o incluso un par de esos pasos) al mismo tiempo usando una expresión regular, iría con las funciones básicas:

Coge la primera mitad (basada en la tercera ubicación de una subcadena "000000") y compara su hash con los siguientes 20 bytes, tirando todo lo que quede.

Uso: strpos() y substr()
O: /$(.*?0{6}.*?0{6}.*?)0{6}/

Luego, tome los siguientes 19 bytes y divídalos en 8 (sorteo 1) y 8.

Use: substr() - (Supongo que quiere decir 17 bytes aquí - 8 + 1 + 8)

$part1 = substr($myStr, $currPos, 8); $part2 = substr($myStr, $currPos + 9, 8);


Depende de tus necesidades. La mayoría de las operaciones de expresión regular son más rápidas de lo que uno pensaría e incluso pueden superar las funciones de cadena incorporadas en ciertas operaciones triviales. Tenga en cuenta que tengo en mente la biblioteca preg, no la biblioteca de expresiones regulares incorporada, que es bastante lenta.


En general, las funciones de cadena son más rápidas y las funciones de expresión regular son más flexibles.

Al igual que con cualquier otra cosa, sus resultados pueden variar, la única forma de saberlo con certeza es probarlo en ambos sentidos y compararlo.


Estaba buscando información sobre el rendimiento de expresiones regulares (ya que necesito hacer muchas búsquedas) y la verdad es que eso depende de lo que quieras lograr . Para mi propósito, probé un tipo de búsqueda para comparar el rendimiento.

Especificación: Necesito encontrar una cadena simple en una matriz de cadenas. Para probar tengo $testArray que es un conjunto de ~ 11k frases de varias palabras $testArray partir del artículo sobre Tolkien (por ejemplo, cadenas "historia del señor de los anillos", "christopher tolkien"). Como quiero encontrar solo frases que contengan la palabra exacta, no puedo usar la función strpos() como p. Al buscar "ring" también encontraría frases con la palabra "ringtone".

Código usando funciones php:

$results = array(); $searchWord = ''rings''; foreach ($testArray as $phrase){ $phraseArr = explode('' '', $phrase); if(in_array($searchWord, $phraseArr)){ $results[] = $phrase; } }

Código usando la función regex:

$results = array(); $pattern= "/( |^)rings( |$)/"; $results = preg_grep($pattern, $testArray);

Descubrí que en este caso la función de expresiones regulares era aproximadamente 10 veces más rápida.

Los tiempos de ejecución para 100 búsquedas fueron (usando varias palabras)

  • De 0.3436 a 0.3468 segundo para funciones php
  • de 0.0332 a 0.0406 segundos para expresiones regulares

Tal búsqueda podría ser trival, pero para tareas más complejas, asumo que sería extremadamente difícil / imposible implementarla sin regex solo en las funciones nativas de PHP.

En conclusión : para tareas sencillas, debe usar regex porque es probable que sea ​​más rápido, y para tareas complejas probablemente tenga que usar expresiones regulares porque sería la única manera de resolver un problema.

Editar:

Me acabo de dar cuenta de que este tema trata sobre las "funciones de cadena de PHP" y mi código de prueba usa las funciones explode() y in_array() . Así que intenté otro enfoque. Como mi delimitador es el método de búsqueda de espacio a continuación, también funciona y utiliza la función strpos() .

Código usando la función strpos() :

$results = array(); $searchWord = ''rings''; foreach ($testArray as $phrase){ if(strpos('' '' . $phrase . '' '', '' '' . $searchWord . '' '')!==FALSE){ $results[] = $phrase; } }

Pero aún los resultados fueron mucho peores que en el caso de expresiones regulares.

Así que el resumen de rendimiento es:

  • De 0.3436 a 0.3468 segundo para las funciones php array
  • de 0.2001 a 0.2273 segundos para la función strpos()
  • de 0.0332 a 0.0406 segundos para expresiones regulares

Todavía regex es un gran ganador.


Estoy de acuerdo con todo el mundo: las funciones de cadena tienen un poco más de rendimiento que las funciones de expresiones regulares. Solo quería mostrar una pequeña prueba, que hice en el terminal como una prueba:

strpos () :

$ time php -r ''$i = 0; while($i++ < 1000000) strpos("abc", "a");'' real 0m0.380s user 0m0.368s sys 0m0.008s

preg_match () :

$ time php -r ''$i = 0; while($i++ < 1000000) preg_match("/abc/", "a");'' real 0m0.441s user 0m0.432s sys 0m0.004s


Las funciones de cadena nativas son mucho más rápidas. El beneficio de la expresión regular es que puedes hacer casi cualquier cosa con ellos.


Si lo que estás haciendo es razonable en absoluto con las funciones de cadena, deberías usarlas. Al igual que, si está determinando si una cadena constante ''abc'' produce en $value , definitivamente desea marcar strpos($value, ''abc'') !== false , no preg_match(''/abc/'', $value) . Sin embargo, si se encuentra haciendo muchas modificaciones y cambios de cadena para lograr lo que hubiera hecho con una expresión regular, es casi seguro que terminará destruyendo el rendimiento y la capacidad de mantenimiento.

Sin embargo, cuando le preocupa la velocidad, cuando se trata de eso, no lo piense, créelo. El comando del time es tu amigo.