¿Puede darnos algunos ejemplos de por qué es difícil analizar XML y HTML con una expresión regular? [cerrado]

Resuelto Chas. Owens asked hace 15 años • 12 respuestas

Un error que veo que la gente comete una y otra vez es intentar analizar XML o HTML con una expresión regular. Estas son algunas de las razones por las que analizar XML y HTML es difícil:

La gente quiere tratar un archivo como una secuencia de líneas, pero esto es válido:

<tag
attr="5"
/>

La gente quiere tratar < o <etiqueta como el inicio de una etiqueta, pero cosas como esta existen en la naturaleza:

<img src="imgtag.gif" alt="<img>" />

La gente a menudo quiere hacer coincidir las etiquetas iniciales con las etiquetas finales, pero XML y HTML permiten que las etiquetas se contengan a sí mismas (lo que las expresiones regulares tradicionales no pueden manejar en absoluto):

<span id="outer"><span id="inner">foo</span></span> 

Las personas a menudo quieren comparar el contenido de un documento (como el famoso problema de "buscar todos los números de teléfono en una página determinada"), pero los datos pueden estar marcados (incluso si parecen normales cuando se ven):

<span class="phonenum">(<span class="area code">703</span>)
<span class="prefix">348</span>-<span class="linenum">3020</span></span>

Los comentarios pueden contener etiquetas mal formateadas o incompletas:

<a href="foo">foo</a>
<!-- FIXME:
    <a href="
-->
<a href="bar">bar</a>

¿Qué otros errores conoces?

Chas. Owens avatar Mar 31 '09 21:03 Chas. Owens
Aceptado

Aquí tienes un XML válido y divertido:

<!DOCTYPE x [ <!ENTITY y "a]>b"> ]>
<x>
    <a b="&y;>" />
    <![CDATA[[a>b <a>b <a]]>
    <?x <a> <!-- <b> ?> c --> d
</x>

Y este pequeño paquete de alegría es HTML válido:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" [
    <!ENTITY % e "href='hello'">
    <!ENTITY e "<a %e;>">
]>
    <title>x</TITLE>
</head>
    <p id  =  a:b center>
    <span / hello </span>
    &amp<br left>
    <!---- >t<!---> < -->
    &e link </a>
</body>

Sin mencionar todo el análisis específico del navegador en busca de construcciones no válidas.

¡Buena suerte enfrentando expresiones regulares contra eso!

EDITAR (Jörg W Mittag): Aquí hay otra buena pieza de HTML 4.01 válido y bien formado:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd"> 
<HTML/
  <HEAD/
    <TITLE/>/
    <P/>
bobince avatar Mar 31 '2009 17:03 bobince

De hecho

<img src="imgtag.gif" alt="<img>" />

no es HTML válido y tampoco es XML válido.

No es XML válido porque '<' y '>' no son caracteres válidos dentro de cadenas de atributos. Deben escaparse utilizando las entidades XML correspondientes < y >

Tampoco es HTML válido porque la forma de cierre breve no está permitida en HTML (pero es correcta en XML y XHTML). La etiqueta 'img' también es una etiqueta implícitamente cerrada según la especificación HTML 4.01. Esto significa que cerrarla manualmente es realmente incorrecto y equivale a cerrar cualquier otra etiqueta dos veces.

La versión correcta en HTML es

<img src="imgtag.gif" alt="&lt;img&gt;">

y la versión correcta en XHTML y XML es

<img src="imgtag.gif" alt="&lt;img&gt;"/>

El siguiente ejemplo que diste tampoco es válido.

<
tag
attr="5"
/>

Esto tampoco es HTML o XML válido. El nombre de la etiqueta debe estar justo detrás del '<', aunque los atributos y el '>' de cierre pueden estar donde quieran. Entonces el XML válido es en realidad

<tag
attr="5"
/>

Y aquí hay otro más divertido: puedes elegir usar " o ' como tu carácter de cita de atributo.

<img src="image.gif" alt='This is single quoted AND valid!'>

Todas las demás razones que se publicaron son correctas, pero el mayor problema con el análisis de HTML es que la gente normalmente no entiende todas las reglas de sintaxis correctamente. El hecho de que su navegador interprete su conjunto de etiquetas como HTML no significa que haya escrito HTML válido.

Editar: E incluso stackoverflow.com está de acuerdo conmigo con respecto a la definición de válido e inválido. Su XML/HTML no válido no está resaltado, mientras que mi versión corregida sí lo está.

Básicamente, XML no está diseñado para ser analizado con expresiones regulares. Pero tampoco hay ninguna razón para hacerlo. Hay muchísimos analizadores XML para todos y cada uno de los idiomas. Puede elegir entre analizadores SAX, analizadores DOM y analizadores Pull. Se garantiza que todo esto será mucho más rápido que analizar con una expresión regular y luego podrá utilizar tecnologías interesantes como XPath o XSLT en el árbol DOM resultante.

Por lo tanto, mi respuesta es: analizar XML con expresiones regulares no solo es difícil, sino que también es una mala idea. Simplemente utilice uno de los millones de analizadores XML existentes y aproveche todas las funciones avanzadas de XML.

HTML es demasiado difícil incluso para intentar analizarlo por tu cuenta. En primer lugar, la sintaxis legal tiene muchas pequeñas sutilezas que quizás no conozcas y, en segundo lugar, el HTML en estado salvaje es sólo una enorme y apestosa pila de (me entiendes). Hay una variedad de bibliotecas de analizadores laxos que hacen un buen trabajo manejando HTML como sopa de etiquetas, solo úselas.

LordOfThePigs avatar Mar 31 '2009 14:03 LordOfThePigs

Escribí una entrada de blog completa sobre este tema: Limitaciones de las expresiones regulares

El quid de la cuestión es que HTML y XML son estructuras recursivas que requieren mecanismos de conteo para poder analizarse correctamente. Una verdadera expresión regular no es capaz de contar. Debes tener una gramática libre de contexto para poder contar.

El párrafo anterior viene con una pequeña advertencia. Ciertas implementaciones de expresiones regulares ahora admiten la idea de recursividad. Sin embargo, una vez que comienzas a agregar recursividad a tus expresiones regulares, realmente estás ampliando los límites y deberías considerar un analizador.

JaredPar avatar Mar 31 '2009 14:03 JaredPar