Las expresiones regulares son una herramienta poderosa en el arsenal del programador, pero hay algunos casos en que no son la mejor opción, o incluso son dañinas.
El ejemplo simple # 1 es analizar HTML con regexp , un camino conocido hacia numerosos errores. Probablemente, esto también se atribuye al análisis en general.
Pero, ¿hay otras áreas claramente prohibidas para las expresiones regulares?
ps: " La pregunta que haces parece subjetiva y es probable que se cierre ". Por lo tanto, quiero enfatizar que estoy interesado en ejemplos en los que se sabe que el uso de expresiones regulares causa problemas.
Respuestas:
No uses expresiones regulares:
Esto no se limita al HTML . Un XML válido simple no se puede analizar razonablemente con una expresión regular, incluso si conoce el esquema y sabe que nunca cambiará.
No intente, por ejemplo, analizar el código fuente de C # . Analízalo en su lugar, para obtener una estructura de árbol significativa o las fichas.
¿Qué sucede si debe buscar una letra, tanto pequeña como mayúscula? Si te encantan las expresiones regulares, las usarás. ¿Pero no es más fácil / rápido / legible usar dos búsquedas, una tras otra? Es probable que en la mayoría de los idiomas logre un mejor rendimiento y haga que su código sea más legible.
Por ejemplo, el código de muestra en la respuesta de Ingo es un buen ejemplo cuando no debe usar expresiones regulares. Solo busca
foo
y luegobar
.Un buen ejemplo es un filtro de obscenidad. No solo es una mala idea en general implementarlo, sino que puede sentirse tentado a hacerlo usando expresiones regulares, y lo hará mal. Hay muchas formas en que un humano puede escribir una palabra, un número, una oración y será entendido por otro humano, pero no su expresión regular. Entonces, en lugar de captar una verdadera obscenidad, su expresión regular pasará su tiempo lastimando a otros usuarios.
Por ejemplo, no valide una dirección de correo electrónico a través de una expresión regular. En la mayoría de los casos, lo harás mal. En un caso raro, lo hará bien y terminará con un horror de codificación de 6 343 caracteres de longitud .
Sin las herramientas adecuadas, cometerás errores. Y los notarás en el último momento, o tal vez nunca. Si no le importa el código limpio, escribirá una cadena de veinte líneas sin comentarios, sin espacios, sin líneas nuevas.
En serio, si tomo su código y debo revisarlo o modificarlo, no quiero pasar una semana tratando de entender una cadena de veinte líneas con muchos símbolos.
fuente
(?(DEFINE))
expresiones regulares ), lea sobre subrutinas, denominadas grupos de captura y aserciones;) Puede escribir expresiones regulares muy limpias usando esas y, en realidad, cuando las use, escribirá gramáticas que son muy similar a lo que escribirías en yacc o similar;)"<a href='foo'>stuff</a>"
. Las expresiones regulares modernas no tienen problemas con esto.Lo más importante: cuando el idioma que está analizando no es un idioma normal .
HTML no es un lenguaje normal y no es posible analizarlo con una expresión regular (no solo es difícil o es un camino hacia un código con errores).
fuente
En stackoverflow, a menudo se ven personas que solicitan expresiones regulares que descubren si una cadena dada no contiene esto o aquello. Esto es, en mi humilde opinión, invirtiendo el propósito de la expresión regular. Incluso si existe una solución (empleando aserciones negativas de retrospectiva o cosas por el estilo), a menudo es mucho mejor usar la expresión regular para lo que fue hecha y manejar el caso negativo con la lógica del programa.
Ejemplo:
fuente
Dos casos:
Cuando hay una manera más fácil
La mayoría de los idiomas proporcionan una función simple como INSTR para determinar si una cadena es un subconjunto de otra. Si eso es lo que quieres hacer, usa la función más simple. No escriba su propia expresión regular.
Si hay una biblioteca disponible para realizar una manipulación compleja de cadenas, úsela en lugar de escribir su propia expresión regular.
Cuando las expresiones regulares no son lo suficientemente potentes
fuente
Las expresiones regulares no pueden identificar estructuras recursivas . Esta es la limitación fundamental.
Tome JSON: es un formato bastante simple, pero dado que un objeto puede contener otros objetos como valores de miembros (arbitrariamente profundos), la sintaxis es recursiva y no puede ser analizada por una expresión regular. Por otro lado, CSV puede ser analizado por expresiones regulares, ya que no contiene ninguna estructura recursiva.
En pocas palabras, las expresiones regulares no permiten que el patrón se refiera a sí mismo. No puede decir: en este punto de la sintaxis coincide con todo el patrón nuevamente. Para decirlo de otra manera, las expresiones regulares solo coinciden linealmente, no contiene una pila que le permita realizar un seguimiento de cuán profundo es un patrón anidado.
Tenga en cuenta que no tiene nada que ver con lo complejo o complicado que es el formato de lo contrario. Las expresiones S son realmente muy simples, pero no se pueden analizar con una expresión regular. CSS2, por otro lado, es un lenguaje bastante complejo, pero no contiene estructuras recursivas y, por lo tanto, se puede analizar con una expresión regular. (Aunque esto no es cierto para CSS3 debido a las expresiones CSS, que tienen una sintaxis recursiva).
Por lo tanto, no es porque sea feo o complejo o propenso a errores para analizar HTML usando solo expresiones regulares. Es que simplemente no es posible .
Si necesita analizar un formato que contiene estructuras recursivas, debe al menos complementar el uso de expresiones regulares con una pila para realizar un seguimiento del nivel de las estructuras recursivas. Esto es típicamente cómo funciona un analizador sintáctico. Las expresiones regulares se usan para reconocer las partes "lineales", mientras que el código personalizado fuera de la expresión regular se usa para realizar un seguimiento de las estructuras anidadas.
Por lo general, el análisis como este se divide en fases separadas. La tokenización es la primera fase donde se usan expresiones regulares para dividir la entrada en una secuencia de "tokens" como palabras, puntuación, corchetes, etc. El análisis es la siguiente fase donde estos tokens se analizan en una estructura jerárquica, un árbol de sintaxis.
Entonces, cuando escuche que HTML o C # no se pueden analizar mediante expresiones regulares, tenga en cuenta que las expresiones regulares siguen siendo una parte crítica de los analizadores. Simplemente no puede analizar dicho lenguaje utilizando solo expresiones regulares y ningún código auxiliar.
fuente