2009-06-15 34 views
18

Alguien que conozco me ha estado diciendo que RegEx debe evitarse, ya que es pesado o implica un procesamiento intenso. ¿Es esto cierto? Esto hizo un aplauso en mis oídos, haciendo sonar mis tímpanos hasta ahora.¿Debo evitar las expresiones regulares?

No sé por qué me dijo eso. ¿Podría haber sido por experiencia o simplemente información de tercera mano (ya sabes a qué me refiero ...)?

Así que, dicho claramente, ¿por qué debería evitar las expresiones regulares?

Quiero información de los maestros de la comunidad SO para compartir sus ideas conmigo. ¡Gracias chicos!

+7

Sí, OpenGL también debe evitarse, se escucha que está lleno de procesamiento pesado ... – 0scar

+1

Vea también: http://stackoverflow.com/questions/842288/are-expressions-regular-over-hyped (que habría sido un una mejor pregunta si el autor había eliminado la pieza de opinión larga ...) – Shog9

+0

No estoy seguro de por qué te molestaron por esa pregunta ...Todo el mundo tiene que empezar en alguna parte y es una buena idea saber por qué o por qué no estás haciendo algo ... +1 – bytebender

Respuesta

26

No las evite.Son una herramienta excelente, y cuando se usa adecuadamente puede ahorrarle mucho tiempo y esfuerzo. Además, una buena implementación utilizada con cuidado no debe ser particularmente intensiva en CPU.

+0

Personalmente, me gusta RegEx, le ahorra una gran cantidad de código (y tiempo) al validar las entradas de texto. podría ser más prudente sacrificar el tiempo de CPU para regex que desgranar el código (que es propenso a errores) ... – jerbersoft

+9

Derecha. Si has pasado los últimos veinte años escribiendo analizadores sintácticos, ahora puedes escribir un equivalente impecable "a mano dura" equivalente a cualquier expresión regular en minutos (con un brazo atado a la espalda, con los ojos vendados ...) Entonces, por supuesto no te molestes con ellos Pero para la mayoría de nosotros, escribir una expresión regular es más rápido que escribir el código de análisis equivalente, ¡incluso si tenemos que buscar la sintaxis mientras lo hacemos! E incluso una expresión moderadamente complicada es más fácil de entender que dos páginas de instrucciones de cambio anidadas ... – Shog9

+2

@ Shog9: Gracias por el aviso del duplicado que se eliminó. Creo que la redacción de esa pregunta fue su caída. Definitivamente vale la pena rescatar las respuestas, así que las fusioné. –

18

¿Sobrevalorado? No. Son extremadamente poderosos y flexibles.

¿Sobreutilizado? Absolutamente. Particularmente cuando se trata de analizar HTML (que a menudo aparece aquí).

Este es otro de esos escenarios de "herramienta adecuada para el trabajo". Algunos van demasiado lejos y tratan de usarlo para todo.

Sin embargo, tiene razón en que puede hacer muchas cosas con subcadena y/o división. A menudo llegarás a un punto en el que lo que estás haciendo se volverá tan complicado que tendrás que cambiar el método o terminarás escribiendo demasiado código frágil. Los regexes son (relativamente) fáciles de expandir.

Pero el código escrito a mano casi siempre será más rápido. Un buen ejemplo de esto es Putting char into a java string for each N characters. La solución de expresiones regulares es más terser pero tiene algunos problemas que un bucle escrito a mano no tiene y es mucho más más lento.

+0

O realmente en cualquier tipo de actividad que se pueda llamar "análisis sintáctico". –

+3

Una expresión regular compilada (bien escrita) en realidad tiende a ser extremadamente rápida. Es solo una máquina de estado. Creo que muchos de los problemas de velocidad pueden atribuirse a personas que no entienden que puede haber una penalización bastante considerable para transformar la representación de cadena de una expresión regular en una expresión regular compilada. – user21714

+1

En realidad, el motor Perl Regex es más rápido que si usted mismo hubiera escrito la rutina, para todos los casos menos los más simples. Por supuesto, esto supone que el Regex estaba bien diseñado para comenzar. –

3

Si más gente supiera cómo usar un generador de analizador decente, habría menos personas usando expresiones regulares.

4

¿Sobrevalorado? No

¿Desproporcionado correctamente? Sí

+0

Recuperé esta respuesta de una pregunta eliminada que era la misma, pero redactada de forma ligeramente diferente. Es posible que desee ajustar la redacción de su respuesta para que coincida. –

5

Creo que si aprende la programación en lenguaje que habla expresiones regulares de forma nativa, gravitará hacia ellas porque simplemente resuelven tantos problemas. Es decir, nunca aprenderás a usar split porque regexec() puede resolver un conjunto más amplio de problemas y, una vez que te acostumbras, ¿por qué buscar en otro lado?

Por otro lado, apuesto a que los programadores C y C++ verán en su mayoría otras opciones primero, ya que no están integradas en el lenguaje.

7

"Cuando tienes un martillo, todo parece un clavo".

Las expresiones regulares son una herramienta muy útil; pero estoy de acuerdo en que no son necesarios para cada lugar donde se usan. Un factor positivo para ellos es que, debido a que tienden a ser complejos y muy utilizados donde están, los algoritmos para aplicar expresiones regulares tienden a estar bastante bien optimizados. Dicho esto, la sobrecarga implicada en aprender las expresiones regulares puede ser ... alta. Muy alto.

¿Son las expresiones regulares la mejor herramienta para usar en todas las situaciones aplicables? Probablemente no, pero, por otro lado, si trabajas con la validación de cadenas y buscas todo el tiempo, probablemente uses mucho las expresiones regulares; y una vez que lo haga, ya tiene el conocimiento necesario para usar la herramienta probablemente de manera más eficiente y rápida que cualquier otra herramienta. Pero si no tienes esa experiencia, aprenderla es efectivamente un lastre para tu productividad para esa implementación.Así que creo que depende de la cantidad de tiempo que esté dispuesto a poner en el aprendizaje de un nuevo paradigma y del nivel de apremio que conlleva su proyecto. En general, creo que vale la pena aprender expresiones regulares, pero al mismo tiempo, ese proceso de aprendizaje puede, francamente, apestar.

3

En mi opinión, la gente los usa demasiado (he tenido esta discusión varias veces en SO).

Pero son una construcción muy útil porque ofrecen una gran cantidad de poder expresivo en un código muy pequeño.

Solo tiene que mirar un ejemplo como el número de registro de un vehículo de Western Australia. El RE sería

re.match("[1-9] [A-Z]{3} [0-9]{3}") 

mientras que el código para comprobar esto sería considerablemente más largo, ya sea en una simple afirmación 9-si-o ligeramente mejor versión de bucle.

casi nunca utilizar RE complejas en mi código porque:

  • Yo sé cómo los motores de RE trabajo y puedo usar el conocimiento del dominio a codificar hasta soluciones más rápidas (que 9 si la variante es casi seguro que será más rápido que un ciclo compilado/ejecutado RE de una sola vez); y
  • Encuentro el código más legible si se divide lógicamente y se comenta. Esto no es fácil con la mayoría de los RE (aunque he visto uno que permite comentarios en línea).

Yo tengo gente vista sugieren el uso de ER para extraer una subcadena de tamaño fijo en un lugar fijo. Por qué estas personas no solo usan substring() me supera. Mi pensamiento personal es que solo están tratando de mostrar cuán astutos son (pero rara vez funciona).

+0

El ejemplo de subcadena() es bastante cierto, y tampoco entiendo por qué algunas personas insisten en usar las expresiones regulares todo el tiempo. –

1

Las expresiones regulares son una de las cosas más útiles que los programadores pueden aprender, permiten acelerar y minimizar tu código si sabes cómo manejarlos.

2

Hay una muy buena razón para usar expresiones regulares en lenguajes de scripting (como Ruby, Python, Perl, JavaScript y Lua): analizar una cadena con expresión regular cuidadosamente optimizada se ejecuta más rápido que el ciclo while personalizado que escanea cadena carácter por carácter. Para los lenguajes compilados (como C y C++, y también C# y Java la mayoría de las veces), generalmente sucede lo contrario: el ciclo while personalizado se ejecuta más rápido.

Una razón más por la cual las expresiones regulares son tan populares: expresan la intención del programador de una manera extremadamente compacta: una expresión regular de línea única puede hacer tanto como un ciclo de 10 o 20 líneas.

1

Las expresiones regulares son a menudo más fáciles de entender que las equivalentes no regex, especialmente en un lenguaje con expresiones regulares nativas, especialmente en una sección de código donde hay otras cosas que deben hacerse con expresiones regulares.

Eso no significa que no se usen en exceso. El único momento en que string.match (/ \? /) Es mejor que string.contains ('?') Es si es significativamente más legible con el código circundante, o si sabes que .contains se implementa con expresiones regulares

1

A menudo uso expresiones regulares en mi IDE para corregir el código rápidamente. Intente hacer lo siguiente sin expresiones regulares.

glVector3f (-1.0f, 1.0f, 1.0f); -> glVector3f (center.x - 1.0f, center.y + 1.0f, center.z + 1.0f);

Sin expresiones regulares, es un dolor, pero con expresiones regulares ...

s/glVector3f\((.*?),(.*?),(.*?)\)/glVector3f(point.x+$1,point.y+$2,point.z+$3)/g 

impresionante.

2

¿Sobrevalorado? No, si alguna vez ha tomado un curso de análisis o compilación, entenderá que esto es como decir "suma" y que la multiplicación está sobrevalorada para los problemas matemáticos.

Es un sistema para resolver problemas de análisis.

algunos problemas son más simples y no requieren expresiones regulares, algunos son más difíciles y requieren mejores herramientas.

+0

@Desconocido: Recuperé esta respuesta al fusionarme de una pregunta eliminada. Es posible que desee ajustar su redacción ligeramente para adaptarse a esta pregunta. –

1

Estoy de acuerdo en que las expresiones regulares a veces se usan de manera inapropiada. Ciertamente, para casos muy simples como lo que describes, pero también para casos en los que se necesita un analizador sintáctico más potente.

Una consideración es que a veces tienes una condición que necesita hacer algo simple como probar la presencia de un carácter de signo de interrogación. Pero a menudo es cierto que la condición se vuelve más compleja. Por ejemplo, para encontrar un carácter de signo de interrogación que no es precedido de un espacio o comienzo de línea, y no es seguido de un carácter alfanumérico. O el personaje puede ser un signo de interrogación o el español "¿" (que puede aparecer al comienzo de una palabra). Entiendes la idea.

Si se espera que las condiciones evolucionen en algo que es menos fácil de hacer con una llamada simple a String.contains("?"), entonces podría ser más fácil codificarlo utilizando una expresión regular muy simple desde el principio.

1

Se trata de la herramienta adecuada para el trabajo.

Normalmente oigo dos argumentos en contra de las expresiones regulares: 1) Son computacionalmente ineficientes, y 2) Son difíciles de entender.

Honestamente, no puedo entender cómo son reclamos legítimos.

1) Esto puede ser cierto en un sentido académico. Una expresión compleja puede volver a doblarse sobre sí misma. De verdad importa? ¿Cuántos millones de cálculos por segundo puede hacer un procesador de servidor estos días? He tratado con algunas expresiones locas expresiones, y he nunca visto una expresión regular ser el cuello de la botella. Por mucho, es la interacción DB, seguido por el ancho de banda.

2) Difícilmente durante aproximadamente una semana. La expresión regular más complicada no es más compleja que HTML, solo es un problema de familiaridad. Si necesitara HTML una vez cada 3 meses, ¿lo obtendría al 100% cada vez? Trabaja con ellos a diario y son tan claros como cualquier sintaxis de otro idioma.

Escribo el software de validación. Los REGEXP son una segunda naturaleza. Cada quinta línea de código tiene una expresión regular, y por mi vida no puedo entender por qué las personas hacen una gran cosa sobre ellos. Nunca he visto un proceso de desaceleración de la expresión regular, y he visto incluso a los 'programadores' más aburridos retomar la sintaxis.

Regexp's son potentes, eficientes y útiles. ¿Por qué evitarlos?

3

No lo evite, pero pregúntese si es la mejor herramienta para la tarea que tiene que resolver. Quizás a veces las expresiones regulares son difíciles de usar o depurar, pero son realmente útiles en algunas situaciones. La pregunta es usar la herramienta apropiada para cada tarea, y generalmente esto no es obvio.

21

Si puede hacer fácilmente lo mismo con operaciones de cadena comunes, entonces debe evitar el uso de una expresión regular.

En la mayoría de las situaciones, las expresiones regulares se utilizan cuando la misma operación requeriría una cantidad sustancial de operaciones de cadenas comunes, por lo que no tiene sentido evitar las expresiones regulares.

+2

Suena como el sentido común, pero las personas parecen olvidar esto. – xenon

+0

¿Cuál es el razonamiento? ¿Por qué un pre compilado en un buen compilador sería mucho más lento que una operación de cadena? –

+2

"El sentido común no es tan común" - Voltaire;) – Guffa

8

Como analizador o validador básico, use una expresión regular a menos que el código de análisis o validación que de lo contrario escribiría sería más fácil de leer.

Para analizadores sintácticos complejos (es decir, analizadores sintácticos de descenso recursivos) use expresiones regulares solo para validar elementos léxicos, no para encontrarlos.

La conclusión es que los mejores motores de expresiones regulares están bien ajustados para el trabajo de validación, y en algunos casos pueden ser más eficientes que el código que usted mismo podría escribir, y en otros su código funcionaría mejor. Escriba su código usando máquinas de estado escritas a mano o expresiones regulares como mejor le parezca, pero cambie de expresiones regulares a código escrito a mano si las pruebas de rendimiento muestran que la expresión regular es significativamente ineficiente.

+2

+1 para señalar que la expresión regular a menudo no es la solución adecuada para los analizadores complejos –

5

Ya sabes, dado que soy lo que mucha gente llama "joven", he oído demasiadas críticas sobre RegEx. Ya sabes, "tuvo un problema e intentó usar expresiones regulares, ahora tiene dos problemas".

En serio, no lo entiendo. Es una herramienta como cualquier otra. Si necesita un sitio web simple con algo de texto, no necesita PHP/ASP.NET/STG44. Aún así, no hay discusión sobre si alguno de esos debe evitarse. Que extraño.

En mi experiencia, RegEx es probablemente la herramienta más útil que he encontrado como desarrollador. Es la herramienta más útil cuando se trata del problema de seguridad n. ° 1: analizar la entrada del usuario. Me he ahorrado horas, si no días, de codificación y la creación de un código potencialmente defectuoso (leer: mierda).

Con las CPU modernas, no veo cuál es el problema de rendimiento aquí. Estoy dispuesto a sacrificar algunos ciclos por algo de calidad y seguridad. (No siempre es el caso, sin embargo, pero creo que esos casos son raros.)

Aún así, RegEx es muy poderoso. Con un gran poder viene una gran responsabilidad. No significa que lo usarás siempre que puedas. Solo donde vale la pena usar su poder.

Como alguien mencionado anteriormente, el análisis de HTML con RegEx es como una ruleta rusa con un arma completamente cargada. No exagere nada, RegEx incluido.

+0

+1 en esta publicación. informativo. – jerbersoft

+2

+1 y amén a eso. Por supuesto que no usas regex donde una simple sustitución de cadenas servirá, pero cualquier programador que no pueda entender sus expresiones regulares no está en la profesión correcta, no es fácil, pero simplemente no * * Así de dificil. – Cruachan

12

Puede sustituir "regex" en su pregunta con prácticamente cualquier tecnología y encontrará personas que entienden poco la tecnología o que son demasiado flojos para aprender la tecnología que hace tales afirmaciones.

No hay nada de pesado en las expresiones regulares. La forma más común en que los programadores se meten en problemas al utilizar expresiones regulares es que intentan hacer demasiado con una sola expresión regular. Si usa expresiones regulares para lo que se pretende (simple coincidencia de patrones), será difícil escribir código de procedimiento que sea más eficiente que la expresión regular equivalente.Con una competencia decente con expresiones regulares, la expresión regular tarda mucho menos tiempo en escribir, es más fácil de leer y puede pegarse en herramientas como RegexBuddy para la visualización.

+0

La gente en el otro extremo del espectro, igualmente ignorante pero entusiasta de todos modos, tampoco ayuda. Los que más me molestan son los que responden a las preguntas de manipulación de cadenas con el consejo, "use regex". ¿Disculpe? Si el OP sabía algo acerca de las expresiones regulares, ¿no crees que las hubiera pensado por sí mismo? A menudo, como no, las expresiones regulares son la herramienta incorrecta para el trabajo de todos modos. (No estoy hablando de este sitio, por cierto, lo veo principalmente en los foros de Java de Sun). –

+0

@ Alan: Correcto. Aunque existen los impulsores de expresiones regulares, este sitio es más un "¿has probado jQuery?" lugar. Por supuesto, jQuery es una pequeña biblioteca fantástica y nadie en su sano juicio debería evitarla ... pero no es la herramienta para cada trabajo. (Específicamente: a veces debe usar expresiones regulares en lugar de jQuery) – Shog9

4

También debe evitar los números de coma flotante a toda costa. Es entonces cuando estás programando en un entorno integrado.

En serio: si está en el desarrollo de software normal, debería utilizar regex si necesita hacer algo que no se puede lograr con operaciones de cadena más simples. Yo diría que cualquier programador normal no podrá implementar algo que se haga mejor utilizando expresiones regulares de una manera que sea más rápida que la expresión regular correspondiente. Una vez compilada, una expresión regular funciona como una máscara de estado que está optimizada casi a la perfección.

2

He visto a mucha gente discutir si una expresión regular dada es correcta o no, estoy empezando a pensar que la mejor manera de escribir una es preguntar cómo hacerlo en StackOverflow y luego dejar que los gurús de la expresión regex peleen fuera.


Creo que son especialmente útiles en JavaScript. JavaScript se transmite (por lo que debe ser pequeño) e interpretado a partir de texto (aunque esto está cambiando en los nuevos navegadores con compilación V8 y JIT), por lo que un buen motor interno de expresiones regulares tiene la posibilidad de ser más rápido que un algoritmo.

Diría que si hay una manera clara y fácil de hacerlo con operaciones de cadena, use las operaciones de cadena. Pero si puede hacer un buen regex en lugar de escribir su propio intérprete de máquina de estado, use la expresión regular.

+0

++ para el caso JS, aunque también se aplica la misma lógica a otros lenguajes interpretados. – Shog9

1

No diría que los evite por completo, ya que son MUY útiles a veces. Sin embargo, es importante comprender los mecanismos fundamentales subyacentes. Dependiendo de su implementación, podría tener hasta el tiempo de ejecución exponencial para una búsqueda, pero como las búsquedas generalmente están limitadas por un número constante de trazas inversas, puede terminar con el tiempo de ejecución lineal más lento que haya visto.

Si quiere la mejor respuesta, tendrá que examinar su implementación particular, así como los datos que desea buscar.

De memoria, wikipedia tiene un artículo decente sobre expresiones regulares y los algoritmos subyacentes.

Cuestiones relacionadas