Al explorar expresiones regulares (también conocidas como RegEx-es), hay muchas personas que parecen ver las expresiones regulares como el Santo Grial. Algo que parece tan complicado, solo debe ser la respuesta a cualquier pregunta. Tienden a pensar que cada problema se puede resolver utilizando expresiones regulares.
Por otro lado, también hay muchas personas que intentan evitar las expresiones regulares a toda costa. Intentan encontrar una forma de evitar las expresiones regulares y aceptan codificación adicional solo por el bien, incluso si una expresión regular sería una solución más compacta.
¿Por qué las expresiones regulares se consideran tan controvertidas? ¿Hay malentendidos generalizados sobre cómo funcionan? ¿O podría ser una creencia generalizada de que las expresiones regulares son generalmente lentas?
Respuestas:
No creo que las personas se opongan a las expresiones regulares porque son lentas, sino porque son difíciles de leer y escribir, así como difíciles de entender. Si bien hay algunas situaciones en las que las expresiones regulares brindan una solución efectiva y compacta al problema, a veces se encuentran en situaciones en las que es mejor usar una sección de código fácil de leer y fácil de mantener.
fuente
|
o.*
), porque usan una máquina de pila y retroceso. Es por eso que debe ajustar cuidadosamente sus expresiones regulares en Perl, Java, Python, Ruby ... Los motores de expresiones regulares de estilo antiguo (engrep
, por ejemplo) primero compilan el patrón en un DFA. Posteriormente, la complejidad del patrón es en gran medida irrelevante. Acabo de usar Java y grep para el mismo texto y patrón: 22min vs 2s. Aquí está la ciencia: swtch.com/~rsc/regexp/regexp1.htmlHacer que las expresiones regulares se mantengan
Un avance importante para desmitificar los patrones anteriormente conocidos como "expresiones regulares" es la
/x
bandera de expresión regular de Perl, a veces escrita(?x)
cuando está incrustada, que permite espacios en blanco (salto de línea, sangría) y comentarios. Esto mejora seriamente la legibilidad y, por lo tanto, la mantenibilidad. El espacio en blanco permite la fragmentación cognitiva, para que pueda ver qué grupos con qué.Los patrones modernos ahora también admiten referencias posteriores relativamente numeradas y con nombre. Eso significa que ya no necesita contar grupos de captura para darse cuenta de que necesita
$4
o\7
. Esto ayuda al crear patrones que se pueden incluir en otros patrones.Aquí hay un ejemplo de un grupo de captura relativamente numerado:
Y aquí hay un ejemplo del enfoque superior de las capturas con nombre:
Expresiones regulares gramaticales
Lo mejor de todo es que estas capturas con nombre se pueden colocar dentro de un
(?(DEFINE)...)
bloque, para que pueda separar la declaración de la ejecución de elementos con nombre individuales de sus patrones. Esto los hace actuar más bien como subrutinas dentro del patrón.Un buen ejemplo de este tipo de "expresión gramatical" se puede encontrar en esta respuesta y en esta . Estos se parecen mucho más a una declaración gramatical.
Como este último te recuerda:
Esto no puede ser sobre enfatizado. Por supuesto, si no usa esas cosas en sus patrones, a menudo creará una pesadilla. Pero si haces uso de ellos, sin embargo, no es necesario.
Aquí hay otro ejemplo de un patrón gramatical moderno, este para analizar RFC 5322: use 5.10.0;
¿No es eso notable y espléndido? ¡Puede tomar una gramática de estilo BNF y traducirla directamente a código sin perder su estructura fundamental!
Si los patrones gramaticales modernos aún no son suficientes para usted, entonces el brillante
Regexp::Grammars
módulo de Damian Conway ofrece una sintaxis aún más limpia, con una depuración superior también. Aquí está el mismo código para analizar RFC 5322 refundido en un patrón de ese módulo:Hay un montón de cosas buenas en la perlre página de manual , pero estas mejoras en las características de diseño de expresiones regulares son fundamentales no se limita a Perl solo. De hecho la pcrepattern página de manual puede ser una lectura más fácil, y cubre el mismo territorio.
Los patrones modernos no tienen casi nada en común con las cosas primitivas que le enseñaron en su clase de autómatas finitos.
fuente
/x
. Es el uso de las expresiones regulares gramaticalmente, con(?&name)
subrutinas de expresiones regulares internas, lo que realmente hace que brille.re.VERBOSE
bandera.Las expresiones regulares son una gran herramienta, pero la gente piensa "¡Oye, qué gran herramienta, la usaré para hacer X!" donde X es algo para lo que una herramienta diferente es mejor (generalmente un analizador sintáctico). Es el estándar que usa un martillo donde necesita un problema de destornillador.
fuente
split($pattern,$string)
vsexplode($delimiter,$string)
: afortunadamente, el primero se está depreciando, pero muchos códigos usaron el primero cuando solo necesitaban el poder del segundo. Agregados, los RegEx proporcionan una herramienta fácil para hacer algunas cosas, pero a menos que necesite todo el poder de las expresiones regulares, ellosCasi todos los que conozco que usan expresiones regulares regularmente (juego de palabras) provienen de un fondo Unix-ish donde usan herramientas que tratan los RE como construcciones de programación de primera clase, como grep, sed, awk y Perl. Como casi no hay sobrecarga sintáctica para usar una expresión regular, su productividad aumenta mucho cuando lo hacen.
Por el contrario, los programadores que usan lenguajes en los que los RE son una biblioteca externa tienden a no considerar qué expresiones regulares pueden aportar a la tabla. El "costo de tiempo" del programador es tan alto que a) los RE nunca aparecieron como parte de su entrenamiento, o b) no "piensan" en términos de los RE y prefieren recurrir a patrones más familiares.
fuente
Las expresiones regulares le permiten escribir una máquina de estados finitos (FSM) personalizada de forma compacta, para procesar una cadena de entrada. Hay al menos dos razones por las que es difícil usar expresiones regulares:
El desarrollo de software de la vieja escuela implica mucha planificación, modelos en papel y una cuidadosa reflexión. Las expresiones regulares se ajustan muy bien a este modelo, porque escribir una expresión efectiva correctamente implica mirarlo fijamente, visualizar los caminos del FSM.
Los desarrolladores de software modernos preferirían forjar el código y usar un depurador para avanzar en la ejecución y ver si el código es correcto. Las expresiones regulares no admiten este estilo de trabajo muy bien. Una "ejecución" de una expresión regular es efectivamente una operación atómica. Es difícil observar la ejecución gradual en un depurador.
Es demasiado fácil escribir una expresión regular que accidentalmente acepte más entradas de las que pretende. El valor de una expresión regular no coincide realmente con una entrada válida, sino que no coincide con una entrada no válida . Las técnicas para hacer "pruebas negativas" para expresiones regulares no son muy avanzadas, o al menos no se usan ampliamente.
Esto va al punto de que las expresiones regulares son difíciles de leer. Con solo mirar una expresión regular, se necesita mucha concentración para visualizar todas las entradas posibles que deberían rechazarse, pero se aceptan por error. ¿Alguna vez trató de depurar el código de expresión regular de otra persona ?
Si existe una resistencia al uso de expresiones regulares entre los desarrolladores de software hoy, creo que se debe principalmente a estos dos factores.
fuente
La gente tiende a pensar que las expresiones regulares son difíciles; pero eso es porque los están usando mal. Escritura de frases complejas sin comentarios, sangría o capturas con nombre. (No abarrota su compleja expresión SQL en una línea, sin comentarios, sangría o alias, ¿verdad?). Entonces sí, para mucha gente, no tienen sentido.
Sin embargo, si su trabajo tiene algo que ver con el análisis de texto (casi cualquier aplicación web existente ...) y no conoce la expresión regular, apesta en su trabajo y está perdiendo su propio tiempo y el de su empleador. Existen excelentes recursos para enseñarle todo lo que necesitará saber sobre ellos, y más.
fuente
x
modificador para expresiones regulares que hace que se ignore el espacio en blanco. Esto le permite poner la expresión regular en unas pocas líneas y agregar comentarios.re.X
akare.VERBOSE
.x
modificador en tcl. Creo que es bastante estándar ya que tcl, a diferencia de otros idiomas, no usa PCRE.Debido a que carecen de la herramienta de aprendizaje más popular en los IDE comúnmente aceptados: no existe el Asistente de expresiones regulares. Ni siquiera Autocompletado. Tienes que codificar todo por ti mismo.
fuente
()
, cuadrados[]
o rizados{}
. También funcionará con la barra invertida." Expresiones regulares: ahora tienes dos problemas " es un excelente artículo de Jeff Atwood sobre el tema. Básicamente, las expresiones regulares son "difíciles". Pueden crear nuevos problemas. Son efectivos, sin embargo.
fuente
No creo que sean tan controvertidos.
También creo que ha respondido su propia pregunta, porque señala lo tonto que sería usarlos en todas partes ( no todo es un lenguaje normal 2 ) o evitar usarlos en absoluto. Usted, el programador, debe tomar una decisión inteligente sobre cuándo las expresiones regulares ayudarán al código o lo dañarán. Cuando se enfrenta a tal decisión, dos cosas importantes a tener en cuenta son la capacidad de mantenimiento (que implica legibilidad) y la extensibilidad.
Para aquellos que son particularmente reacios a ellos, supongo que nunca aprendieron a usarlos adecuadamente. Creo que la mayoría de las personas que pasan unas pocas horas con un tutorial decente los descubrirán y hablarán con fluidez muy rápidamente. Aquí está mi sugerencia sobre dónde comenzar:
http://docs.python.org/howto/regex
Aunque esa página habla de expresiones regulares en el contexto de Python, he encontrado que la información es muy aplicable en otros lugares. Hay algunas cosas que son específicas de Python, pero creo que se notan claramente y son fáciles de recordar.
fuente
Las expresiones regulares son para cadenas lo que los operadores aritméticos son para números, y no los consideraría controvertidos. Creo que incluso un activista OO bastante militante como yo (que tendería a elegir otros objetos en lugar de cadenas) sería difícil rechazarlos.
fuente
El problema es que las expresiones regulares son potencialmente tan poderosas que puedes hacer cosas con ellas para las que deberías usar algo diferente.
Un buen programador debe saber dónde usarlos y dónde no. El ejemplo típico es analizar idiomas no regulares (consulte Decidir si un idioma es regular ).
Creo que no puedes equivocarte si al principio te limitas a expresiones regulares reales (sin extensiones). Algunas extensiones pueden hacer su vida un poco más fácil, pero si encuentra algo difícil de expresar como una expresión regular real , esto puede ser una indicación de que una expresión regular no es la herramienta correcta.
fuente
Es muy probable que se pregunte por qué los goto son controvertidos.
Básicamente, cuando obtienes tanto poder "obvio", las personas tienden a abusar de ellos en situaciones para las que no son la mejor opción. La cantidad de personas que piden analizar CSV o XML o HTML en expresiones regulares, por ejemplo, me asombra. Es la herramienta incorrecta para el trabajo. Pero algunos usuarios insisten en usar expresiones regulares de todos modos.
Personalmente, trato de encontrar ese medio feliz: use expresiones regulares para lo que son buenas y evítelas cuando no sean óptimas.
Tenga en cuenta que las expresiones regulares todavía se pueden usar para analizar CSV, XML, HTML, etc. Pero generalmente no en una sola expresión regular.
fuente
No creo que "controvertido" sea la palabra correcta.
Pero he visto toneladas de ejemplos en los que la gente dice "¿cuál es la expresión regular que necesito para hacer tal y tal manipulación de cadenas?" que son problemas XY
En otras palabras, comenzaron desde el supuesto de que una expresión regular es lo que necesitan, pero sería mejor con una división (), una traducción como perl's tr /// donde los caracteres se sustituyen uno por el otro, o solo un índice ().
fuente
Este es un tema interesante.
Muchos aficionados a expresiones regulares parecen confundir la concisión de la fórmula con la eficiencia.
Además de eso, una expresión regular que requiere mucho pensamiento produce a su autor una satisfacción masiva que lo hace legítimo de inmediato.
Pero ... las expresiones regulares son muy convenientes cuando el rendimiento no es un problema y necesita tratar rápidamente con una salida de texto, en Perl, por ejemplo. Además, si bien el rendimiento es un problema, uno puede preferir no tratar de superar la biblioteca regexp mediante el uso de un algoritmo casero que puede tener errores o ser menos eficiente.
Además, hay una serie de razones por las cuales las expresiones regulares son injustamente criticadas, por ejemplo
fuente
Lo que creo es que Learning Regex y el mantenimiento de expresiones regulares no son populares, la mayoría de los desarrolladores son flojos o la mayoría de ellos confían en bibliotecas externas para que hagan el análisis por ellos ... confían en Google para obtener la respuesta e incluso preguntan en foros por El código completo para su problema. Pero cuando se trata de implementar o modificar / mantener una expresión regular, simplemente fallan.
Hay un dicho popular que dice "Los amigos no permiten que los amigos usen Regex para analizar HTML"
Pero en lo que a mí respecta, he realizado analizadores HTML completos utilizando Regex y creo que regex es mejor para analizar cadenas html tanto en velocidad como en memoria (si tienes una idea de lo que debes lograr :))
fuente
Las expresiones regulares son un misterio serio para muchas personas, incluido yo mismo. Funciona muy bien, pero es como mirar una ecuación matemática. Sin embargo, me complace informar que alguien finalmente ha creado una ubicación consolidada de varias funciones de expresión regular en http://regexlib.com/ . Ahora, si Microsoft solo creara una clase de expresión regular que automáticamente hiciera muchas de las cosas comunes como eliminar letras o filtrar fechas.
fuente
Encuentro expresiones regulares invaluables a veces. Cuando necesito hacer algunas búsquedas "difusas", y tal vez reemplaza. Cuando los datos pueden variar y tener una cierta aleatoriedad. Sin embargo, cuando necesito hacer una simple búsqueda y reemplazo, o verificar una cadena, no uso expresiones regulares. Aunque conozco a muchas personas que lo hacen, lo usan para todo. Esa es la controversia.
Si quieres poner una tachuela en la pared, no uses un martillo. Sí, funcionará, pero para cuando obtengas el martillo, podría poner 20 tachuelas en la pared.
Las expresiones regulares deben usarse para lo que fueron diseñadas, y nada menos.
fuente
Si bien creo que las expresiones regulares son una herramienta esencial, lo más molesto de ellas es que existen diferentes implementaciones. Las pequeñas diferencias en la sintaxis, los modificadores y, especialmente, la "codicia" pueden hacer que las cosas sean realmente caóticas, requiriendo prueba y error y, a veces, generando errores desconcertantes.
fuente
En algunos casos creo que tienes que usarlos. Por ejemplo para construir un lexer.
En mi opinión, este es un punto de vista de las personas que pueden escribir expresiones regulares y las personas que no (o apenas). Personalmente, creo que esta es una buena idea, por ejemplo, para validar la entrada de un formulario, ya sea en JavaScript para advertir al usuario, o en un lenguaje del lado del servidor.
fuente
Creo que es una técnica menos conocida entre los programadores. Por lo tanto, no hay una amplia aceptación para ello. Y si tiene un gerente no técnico para revisar su código o revisar su trabajo, entonces una expresión regular es muy mala. Pasará horas escribiendo una expresión regular perfecta, y obtendrá pocas marcas para el módulo pensando que él / ella ha escrito tan pocas líneas de código. Además, como se dijo en otra parte, leer expresiones regulares es una tarea muy difícil.
fuente
Los sistemas de expresión regular decentes, como los utilizados en lex y yacc para la definición del compilador, son buenos, muy útiles y limpios. En estos sistemas, los tipos de expresión se definen en términos de otros. Son las expresiones regulares horribles mal formadas, ilegibles, gigantescas, de un solo trazo, que se encuentran comúnmente en el código perl y sed (etc.) que son 'controvertidas' (basura).
fuente
El mejor uso válido y normal para regex es para la validación del formato de dirección de correo electrónico.
Esa es una buena aplicación.
He usado expresiones regulares innumerables veces como únicas en TextPad para masajear archivos planos, crear archivos csv, crear declaraciones de inserción SQL y ese tipo de cosas.
Las expresiones regulares bien escritas no deberían ser demasiado lentas. Por lo general, las alternativas, como toneladas de llamadas a Reemplazar, son opciones mucho más lentas. También podría hacerlo de una sola vez.
Muchas situaciones requieren expresiones regulares y nada más.
Reemplazar caracteres especiales que no se imprimen con caracteres inocuos es otro buen uso.
Por supuesto, puedo imaginar que hay algunas bases de código que usan en exceso las expresiones regulares en detrimento de la mantenibilidad. Nunca lo he visto yo mismo. De hecho, los revisores de código me han evitado que no use suficientes expresiones regulares.
fuente