Usar expresiones regulares para analizar HTML: ¿por qué no?

Resuelto ntownsend asked hace 15 años • 18 respuestas

Parece que cada pregunta en stackoverflow en la que el autor de la pregunta usa expresiones regulares para obtener información de HTML inevitablemente tendrá una "respuesta" que dice no usar expresiones regulares para analizar HTML.

¿Por qué no? Soy consciente de que existen analizadores HTML "reales" entre comillas como Beautiful Soup , y estoy seguro de que son potentes y útiles, pero si solo estás haciendo algo simple, rápido o sucio, entonces ¿por qué? ¿Te molesta usar algo tan complicado cuando algunas declaraciones de expresiones regulares funcionarán bien?

Además, ¿hay algo fundamental que no entiendo acerca de las expresiones regulares que las convierte en una mala opción para el análisis en general?

ntownsend avatar Feb 26 '09 21:02 ntownsend
Aceptado

El análisis completo de HTML no es posible con expresiones regulares, ya que depende de hacer coincidir las etiquetas de apertura y cierre, lo que no es posible con expresiones regulares.

Las expresiones regulares solo pueden coincidir con lenguajes regulares , pero HTML es un lenguaje libre de contexto y no un lenguaje regular (como señaló @StefanPochmann, los lenguajes regulares también están libres de contexto, por lo que libre de contexto no significa necesariamente que no sean regulares). Lo único que puede hacer con las expresiones regulares en HTML es la heurística, pero eso no funcionará en todas las condiciones. Debería ser posible presentar un archivo HTML que coincida incorrectamente con cualquier expresión regular.

Johannes Weiss avatar Feb 26 '2009 14:02 Johannes Weiss

Para una expresión regular rápida y sucia funcionará bien. Pero lo fundamental que hay que saber es que es imposible construir una expresión regular que analice HTML correctamente .

La razón es que las expresiones regulares no pueden manejar expresiones anidadas arbitrariamente. Consulte ¿Se pueden utilizar expresiones regulares para hacer coincidir patrones anidados?

kmkaplan avatar Feb 26 '2009 14:02 kmkaplan

(De http://htmlparsing.com/regexes )

Supongamos que tiene un archivo HTML donde intenta extraer URL de etiquetas <img>.

<img src="http://example.com/whatever.jpg">

Entonces escribes una expresión regular como esta en Perl:

if ( $html =~ /<img src="(.+)"/ ) {
    $url = $1;
}

En este caso, $urlde hecho contendrá http://example.com/whatever.jpg. Pero, ¿qué sucede cuando empiezas a recibir HTML como este?

<img src='http://example.com/whatever.jpg'>

o

<img src=http://example.com/whatever.jpg>

o

<img border=0 src="http://example.com/whatever.jpg">

o

<img
    src="http://example.com/whatever.jpg">

o empiezas a recibir falsos positivos de

<!-- // commented out
<img src="http://example.com/outdated.png">
-->

Parece muy simple, y podría serlo para un único archivo que no cambia, pero para cualquier cosa que vayas a hacer con datos HTML arbitrarios, las expresiones regulares son solo una receta para futuros dolores de cabeza.

Andy Lester avatar Sep 10 '2013 17:09 Andy Lester

Dos razones rápidas:

  • escribir una expresión regular que pueda resistir entradas maliciosas es difícil; mucho más difícil que usar una herramienta prediseñada
  • escribir una expresión regular que pueda funcionar con el ridículo marcado con el que inevitablemente te quedarás atrapado es difícil; mucho más difícil que usar una herramienta prediseñada

Con respecto a la idoneidad de las expresiones regulares para el análisis en general: no son adecuadas. ¿Alguna vez has visto los tipos de expresiones regulares que necesitarías para analizar la mayoría de los idiomas?

Hank Gay avatar Feb 26 '2009 14:02 Hank Gay

En lo que respecta al análisis, las expresiones regulares pueden resultar útiles en la etapa de "análisis léxico" (lexer), donde la entrada se divide en tokens. Es menos útil en la etapa real de "construir un árbol de análisis".

Para un analizador HTML, esperaría que solo aceptara HTML bien formado y eso requiere capacidades fuera de lo que puede hacer una expresión regular (no pueden "contar" y asegurarse de que un número determinado de elementos de apertura estén equilibrados por el mismo número de elementos de cierre).

Vatine avatar Feb 26 '2009 14:02 Vatine