2010-09-20 22 views
6

Esta pregunta está diseñada en torno al rendimiento en PHP, pero puede ampliarla a cualquier idioma si lo desea.'Expresión regular' VS 'Operadores/funciones de comparación de cadenas'

Después de muchos años de usar PHP y tener que comparar cadenas, he aprendido que usar operadores de comparación de cadenas en expresiones regulares es beneficioso cuando se trata de rendimiento.

Entiendo completamente que algunas operaciones tienen que hacerse con expresiones regulares hasta su complejidad, pero para las operaciones que se pueden resolver a través de las funciones de cadena Y regex.

tomar este ejemplo:

PHP

preg_match('/^[a-z]*$/','thisisallalpha'); 

C#

new Regex("^[a-z]*$").IsMatch('thisisallalpha'); 

se puede hacer fácilmente con

PHP

ctype_alpha('thisisallalpha'); 

C#

VFPToolkit.Strings.IsAlpha('thisisallalpha'); 

Hay muchos otros ejemplos, pero usted debe conseguir el punto que estoy tratando de hacer.

¿Qué versión de la comparación de cadenas debe intentar inclinarse hacia y por qué?

+0

Sus ejemplos fallarán porque las cadenas contienen espacios. –

+0

Ese no es el punto aquí, tratando de obtener algunos votos :) – RobertPitt

+2

Los corregiría de todos modos. Educar con exaples correctos. – gertas

Respuesta

6

Parece que esta pregunta surgió de nuestro pequeño argumento here, por lo que me siento de alguna manera obligado a responder.

php desarrolladores están siendo activamente lavados de cerebro sobre el "rendimiento", por lo que surgen muchos rumores y mitos, incluyendo cosas estúpidas como "las comillas dobles son más lentas". Regexps es "lento" es uno de estos mitos, desafortunadamente respaldado por el manual (ver infame comentario en la página preg_match). La verdad es que en la mayoría de los casos no te importa. A menos que su código se repita 10.000 veces, ni siquiera nota una diferencia entre la función de cadena y una expresión regular. Y si tu código se repite 10.000 veces, debes estar haciendo algo mal en cualquier caso, y obtendrás rendimiento optimizando tu lógica, no eliminando las expresiones regulares.

En cuanto a la legibilidad, las expresiones regulares son reconocidamente difícil de leer, sin embargo, el código que los utiliza es en la mayoría de los casos más corto, más limpio y más sencillo (compárese con la suya y respuestas de la mina en el enlace anterior).

Otra preocupación importante es la flexibilidad, especialmente en php, cuya biblioteca de cadenas no admite el Unicode de fábrica. En su ejemplo concreto, ¿qué sucede cuando decide migrar su sitio a utf8? Con ctype_alpha está un poco fuera de suerte, preg_match requeriría otro patrón, pero seguirá trabajando.

Por lo tanto, las expresiones regulares no son más lentas, más legibles y más flexibles. ¿Por qué deberíamos evitarlos?

+0

Sí, surgió de esa pequeña "conversación", y pensé que sería mejor obtener las opiniones de otros programadores sobre el tema antes de saltar, Gracias por su visión +1 , pero como dije, no evito las expresiones regulares, solo creo que para ahorrarles algunos peta-segundos me inclinaría hacia las funciones de cadena, a medida que mi aplicación crezca, cada poco ayuda. – RobertPitt

+10

Erm _ "si su código se repite 10.000 veces, debe estar haciendo algo mal en cualquier caso" _ => Estoy discretamente de acuerdo en que este _debe ser el caso. Ciertamente hay casos válidos. – Wrikken

+0

* ... cosas estúpidas como "comillas dobles son más lentas" ... * –

0

Ambos son parte del lenguaje por una razón. IsAlpha es más expresivo. Por ejemplo, cuando una expresión que está viendo es intrínsecamente alfa o no, y eso tiene un significado de dominio, entonces úsela.

Pero si se trata, por ejemplo, de una validación de entrada, y podría modificarse para incluir guiones bajos, guiones, etc., o si es con otra lógica que requiere expresiones regulares, entonces usaría expresiones regulares. Esto tiende a ser la mayor parte del tiempo para mí.

+0

Thans por su respuesta, lo sé, se menciona en mi publicación original, lo que mis pensamientos eran, es para las operaciones que se pueden manejar con ambos métodos, ¿por cuál uno se opondría y por qué? – RobertPitt

+0

Editado para abordar mejor su pregunta (espero) –

1

Las expresiones regulares realmente conducen a una ganancia de rendimiento (no es que tales microoptimizaciones sean de ninguna manera sensatas) cuando pueden reemplazar comparaciones múltiples de cadenas atómicas. Por lo general, alrededor de cinco strpos() comprueba que es aconsejable utilizar una expresión regular en su lugar. Moreso para la legibilidad.

Y aquí hay otro pensamiento para completar las cosas: PCRE puede manejar condicionales más rápido de lo que el kernel Zend puede manejar el bytecode IF.

No todas las expresiones regulares son iguales. Si el complejo se vuelve demasiado alto, la recursión de expresiones regulares puede matar su ventaja de rendimiento. Por lo tanto, a menudo es reconsiderable mezclar expresiones regulares y funciones regulares de PHP. Herramienta correcta para el trabajo y todo.

1

PHP en sí recomienda utilizar funciones de cadena sobre las funciones de expresiones regulares cuando la coincidencia es directa. Por ejemplo, desde la página de manual de preg_match:

No usar preg_match() si sólo se desea comprobar si una cadena está contenida en otra cadena. Use strpos() o strstr(), ya que serán más rápidos.

o desde la página str_replace Manual:

Si no es necesario reemplazar las reglas de fantasía (como expresiones regulares), siempre debe utilizar esta función en lugar de ereg_replace() o preg_replace().

Sin embargo, encuentro que las personas intentan usar las funciones de cadena para resolver problemas que se resolverían mejor con regex. Por ejemplo, cuando trato de crear un matcher de cadenas de palabras completas, he encontrado personas que intentan usar strpos($string, " $word ") (tenga en cuenta los espacios), por el bien de "rendimiento", sin detenerse a pensar cómo los espacios no son la única manera de delinear una palabra (piense en cuántas llamadas de funciones de cadena se necesitarían para reemplazar por completo preg_match('/\bword\b/', $string)).

Mi postura personal es utilizar funciones de cadena para hacer coincidir cadenas estáticas (es decir, una coincidencia de una secuencia distinta de caracteres donde la coincidencia es siempre la misma) y expresiones regulares para todo lo demás.

0

Estoy de acuerdo con que las personas con PHP tienden a sobre enfatizar el rendimiento de una función sobre otra. Eso no significa que las diferencias de rendimiento no existen, definitivamente sí lo tienen, pero la mayoría del código PHP (y de hecho la mayoría del código en general) tiene mucho más cuellos de botella que la elección de expresiones regulares sobre comparación de cadenas. Para saber dónde están los cuellos de botella, use el generador de perfiles de xdebug. Solucione los problemas que surgen antes de preocuparse por ajustar líneas de código individuales.

Cuestiones relacionadas