Un error que veo que la gente comete una y otra vez es tratar de 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 la etiqueta <o <como el comienzo 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 finales, pero XML y HTML permiten que las etiquetas se contengan a sí mismas (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 con el contenido de un documento (como el famoso problema "encontrar todos los números de teléfono en una página determinada"), pero los datos pueden estar marcados (incluso si parece ser normal cuando se ve):
<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>
¿De qué otras cosas te das cuenta?
Respuestas:
Aquí hay un divertido XML válido para ti:
Y este pequeño paquete de alegría es HTML válido:
Sin mencionar todo el análisis específico del navegador para 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:
fuente
Realmente
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 las cadenas de atributos. Deben escapar utilizando las entidades XML correspondientes & lt; y & gt;
Tampoco es HTML válido porque el formulario de cierre corto no está permitido en HTML (pero es correcto 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 cerrarlo manualmente es realmente incorrecto y es equivalente a cerrar cualquier otra etiqueta dos veces.
La versión correcta en HTML es
y la versión correcta en XHTML y XML es
El siguiente ejemplo que diste también es inválido
Esto tampoco es HTML o XML válido. El nombre de la etiqueta debe estar justo detrás de '<', aunque los atributos y el cierre '>' pueden estar donde quieran. Entonces el XML válido es en realidad
Y aquí hay otro más funky: en realidad puede elegir usar "o" como su carácter de cita de atributo
Todas las otras razones que se publicaron son correctas, pero el mayor problema al analizar HTML es que las personas generalmente no entienden todas las reglas de sintaxis correctamente. El hecho de que su navegador interprete su tagoup 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í.
Básicamente, XML no está hecho para ser analizado con expresiones regulares. Pero tampoco hay razón para hacerlo. Hay muchos, muchos analizadores XML para cada idioma. Puede elegir entre analizadores SAX, analizadores DOM y analizadores Pull. Se garantiza que todo esto será mucho más rápido que el análisis con una expresión regular y luego puede usar tecnologías geniales como XPath o XSLT en el árbol DOM resultante.
Por lo tanto, mi respuesta es: no solo analizar XML con regexps es difícil, sino que también es una mala idea. Simplemente use uno de los millones de analizadores XML existentes y aproveche todas las características avanzadas de XML.
HTML es demasiado difícil incluso intentar analizarlo usted mismo. Primero, la sintaxis legal tiene muchas pequeñas sutilezas de las que quizás no estés al tanto, y segundo, HTML en la naturaleza es solo una enorme pila apestosa (me entiendes). Hay una variedad de bibliotecas de analizadores laxas que hacen un buen trabajo al manejar HTML como la sopa de etiquetas, solo utilícelas.
fuente
>
el signo es perfectamente válido en html stackoverflow.com/questions/94528/…Escribí una entrada de blog completa sobre este tema: Limitaciones de expresión regular
El quid de la cuestión es que HTML y XML son estructuras recursivas que requieren mecanismos de recuento para analizar correctamente. Una verdadera expresión regular no es capaz de contar. Debe tener una gramática libre de contexto para contar.
El párrafo anterior viene con una leve advertencia. Ciertas implementaciones de expresiones regulares ahora admiten la idea de recursividad. Sin embargo, una vez que comience a agregar recursividad a sus expresiones regulares, realmente está extendiendo los límites y debería considerar un analizador sintáctico.
fuente
Una cosa que no está en su lista es que los atributos pueden aparecer en cualquier orden, por lo que si su expresión regular está buscando un enlace con el href "foo" y la clase "bar", pueden aparecer en cualquier orden y tener cualquier otro número cosas entre ellos
fuente
Depende de lo que quieras decir con "análisis". En términos generales, XML no se puede analizar utilizando expresiones regulares, ya que la gramática XML no es regular. En pocas palabras, las expresiones regulares no pueden contar (bueno, las expresiones regulares de Perl en realidad podrían contar cosas), por lo que no puede equilibrar las etiquetas de apertura-cierre.
fuente
¿Las personas realmente están cometiendo un error al usar una expresión regular, o simplemente es lo suficientemente bueno para la tarea que están tratando de lograr?
Estoy totalmente de acuerdo en que analizar html y xml usando una expresión regular no es posible, ya que otras personas han respondido.
Sin embargo, si su requisito no es analizar html / xml, sino obtener un pequeño bit de datos en un bit "html / xml" conocido "bueno, entonces tal vez una expresión regular o incluso una" subcadena "aún más simple sea suficiente.
fuente
Las personas normalmente escriben patrones codiciosos, a menudo lo suficiente como para que no se piense bien. * Arrastrando grandes trozos de archivo al <foo>. * </foo> más grande posible.
fuente
.*?<
, puedes arreglar eso usando una clase de caracteres negada como[^<]*<
. (Descargo de responsabilidad: obviamente, eso todavía no es infalible, que es el punto de la pregunta.)Estoy tentado a decir "no reinventes la rueda". Excepto que XML es un formato realmente complejo. Entonces quizás debería decir "no reinventes el sincrotrón".
Quizás el cliché correcto comienza "cuando todo lo que tienes es un martillo ..." Sabes cómo usar expresiones regulares, las expresiones regulares son buenas para analizar, así que ¿por qué molestarse en aprender una biblioteca de análisis XML?
Porque analizar XML es difícil . Cualquier esfuerzo que ahorre al no tener que aprender a usar una biblioteca de análisis XML estará más que compensado por la cantidad de trabajo creativo y la eliminación de errores que tendrá que hacer. Por su propio bien, busque en Google "biblioteca XML" y aproveche el trabajo de otra persona.
fuente
Creo que este clásico tiene la información que estás buscando. Puede encontrar el punto en uno de los comentarios allí:
Alguna información más de Wikipedia: Jerarquía Chomsky
fuente
Creo que los problemas se reducen a:
La expresión regular es casi siempre incorrecta. Hay entradas legítimas que no coincidirán correctamente. Si trabajas lo suficiente, puedes hacer que sea 99% correcto, o 99.999%, pero hacerlo 100% correcto es casi imposible, aunque solo sea por las cosas extrañas que XML permite al usar entidades.
Si la expresión regular es incorrecta, incluso para el 0.00001% de las entradas, entonces tiene un problema de seguridad, porque alguien puede descubrir la única entrada que romperá su aplicación.
Si la expresión regular es lo suficientemente correcta como para cubrir el 99,99% de los casos, será completamente ilegible e imposible de mantener.
Es muy probable que una expresión regular funcione muy mal en archivos de entrada de tamaño moderado. Mi primer encuentro con XML fue reemplazar un script de Perl que (incorrectamente) analizaba los documentos XML entrantes con un analizador XML adecuado, y no solo reemplazamos 300 líneas de código ilegible con 100 líneas que cualquiera podría entender, sino que mejoramos el tiempo de respuesta del usuario de 10 segundos a aproximadamente 0.1 segundos.
fuente
Estoy en desacuerdo. Si va a utilizar recursivo en expresiones regulares, puede encontrar fácilmente las etiquetas de apertura y cierre.
Aquí mostré ejemplos de expresiones regulares para evitar errores de análisis de ejemplos en el primer mensaje.
fuente
Di una respuesta simplificada a este problema aquí . Si bien no representa la marca del 100%, explico cómo es posible si está dispuesto a hacer un trabajo de preprocesamiento.
fuente