tag regular online one for expressions html xml regex

online - regular expression for html



¿Puede proporcionar algunos ejemplos de por qué es difícil analizar XML y HTML con una expresión regular? (12)

Un error que veo que la gente hace over y otra vez es tratar de analizar XML o HTML con una expresión regular. Estas son algunas de las razones por las que el análisis de 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 inicio de una etiqueta, pero este tipo de cosas existen en la naturaleza:

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

Las personas a menudo desean hacer coincidir las etiquetas de inicio con las etiquetas de finalización, pero XML y HTML permiten que las etiquetas se contengan (lo que las expresiones regulares tradicionales no pueden manejar en absoluto):

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

Las personas a menudo desean coincidir con el contenido de un documento (como el famoso problema "buscar todos los números de teléfono en una página dada"), 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>

¿Qué otras trampas conoces?


En general, XML no se puede analizar utilizando expresiones regulares ya que la gramática XML no es de ninguna manera regular. En pocas palabras, las expresiones regulares no pueden contar (bueno, las expresiones regulares de Perl pueden realmente ser capaces de contar cosas), por lo que no puede equilibrar las etiquetas de apertura y cierre.

Estoy en desacuerdo. Si va a utilizar recursivo en expresiones regulares, puede encontrar fácilmente etiquetas de abrir y cerrar.

Here mostré un ejemplo de expresión regular para evitar analizar errores de ejemplos en el primer mensaje.


¿Las personas realmente están cometiendo un error al usar una expresión regular, o es simplemente lo suficientemente buena para la tarea que están tratando de lograr?

Estoy totalmente de acuerdo en que el análisis de html y xml con una expresión regular no es posible ya que otras personas han respondido.

Sin embargo, si su requerimiento no es analizar html / xml sino simplemente obtener un pequeño bit de datos en un bit "bueno conocido" de html / xml, entonces tal vez una expresión regular o incluso una "subcadena" aún más simple sea suficiente.


Actualmente

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

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

No es un XML válido porque ''<'' y ''>'' no son caracteres válidos dentro de las cadenas de atributo. Deben escaparse utilizando las entidades XML correspondientes & lt; y & gt;

Tampoco es un HTML válido porque la forma de cierre corto no está permitida en HTML (pero es correcta en XML y XHTML). La etiqueta ''img'' también es una etiqueta cerrada implícitamente 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 dio también es inválido

< tag attr="5" />

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 lo deseen. Así que el XML válido es en realidad

<tag attr="5" />

Y aquí hay otro más divertido: en realidad, puedes elegir usar "o" como tu atributo de comillas.

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

Todas las otras razones que se publicaron son correctas, pero el mayor problema con el análisis de HTML es que las personas generalmente no entienden todas las reglas de sintaxis correctamente. El hecho de que su navegador interprete su tagsoup como HTML no significa que haya escrito realmente un HTML válido.

Edit: E incluso .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á 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 de extracción. Se garantiza que todo esto será mucho más rápido que el análisis con una expresión regular y entonces puede usar tecnologías geniales como XPath o XSLT en el árbol DOM resultante.

Por lo tanto, mi respuesta es: no solo es difícil analizar XML con expresiones regulares, 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 para intentar analizar por su cuenta. Primero, la sintaxis legal tiene muchas pequeñas sutilezas que quizás no conozcas, y segundo, el HTML en la naturaleza es solo una enorme pila apestosa (me entiendes). Hay una variedad de bibliotecas de analizador laxas que hacen un buen trabajo en el manejo de HTML como la sopa de etiquetas, solo use estas.


Aquí hay un divertido XML válido para ti:

<!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 todos los análisis específicos del navegador para construcciones inválidas.

Buena suerte enfrentando a regex 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/>


Creo que this clásico tiene la información que estás buscando. Puedes encontrar el punto en uno de los comentarios allí:

Creo que la falla aquí es que HTML es una gramática de Chomsky Type 2 (gramática sin contexto) y RegEx es una gramática de Chomsky Type 3 (expresión regular). Dado que una gramática de Tipo 2 es fundamentalmente más compleja que una gramática de Tipo 3, no puede esperar hacer que esto funcione . Pero muchos lo intentarán, algunos reclamarán el éxito y otros encontrarán la falla y lo arruinarán totalmente.

Un poco más de información de Wikipedia: Jerarquía de Chomsky


Creo que los problemas se reducen a:

  1. La expresión regular es casi siempre incorrecta. Hay entradas legítimas que no podrán coincidir correctamente. Si trabajas lo suficientemente duro, puedes hacerlo correcto al 99%, o 99.999%, pero hacerlo al 100% correcto es casi imposible, aunque solo sea por las cosas raras que permite el XML mediante el uso de entidades.

  2. 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.

  3. Si la expresión regular es lo suficientemente correcta como para cubrir el 99.99% de los casos, entonces será completamente ilegible e inalcanzable.

  4. Es muy probable que una expresión regular se desempeñe muy mal en archivos de entrada de tamaño moderado. Mi primer encuentro con XML fue reemplazar un script Perl que analizaba (incorrectamente) 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 unos 0,1 segundos.


Depende de lo que quiere decir con "análisis". En general, XML no se puede analizar utilizando expresiones regulares ya que la gramática XML no es de ninguna manera regular. En pocas palabras, las expresiones regulares no pueden contar (bueno, las expresiones regulares de Perl pueden realmente ser capaces de contar cosas), por lo que no puede equilibrar las etiquetas de apertura y cierre.


Di una respuesta simplificada a este problema here . Si bien no representa la marca del 100%, explico cómo es posible si está dispuesto a realizar un trabajo de preprocesamiento.


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

El quid de la cuestión es que HTML y XML son estructuras recursivas que requieren mecanismos de conteo para analizar correctamente. Un verdadero regex no es capaz de contar. Debes tener una gramática libre de contexto para poder contar.

El párrafo anterior viene con una ligera advertencia. Ciertas implementaciones de expresiones regulares ahora apoyan la idea de recursión. Sin embargo, una vez que comience a agregar recursión en sus expresiones de expresiones regulares, realmente está estirando los límites y debe considerar un analizador.


Estoy tentado de decir "no reinventar la rueda". Excepto que XML es un formato muy, muy complejo. Así que tal vez debería decir "no reinventar el sincrotrón".

Quizás el cliché correcto comience "cuando todo lo que tienes es un martillo ..." Sabes cómo usar expresiones regulares, las expresiones regulares son buenas para el análisis, así que, ¿por qué molestarse en aprender una biblioteca de análisis XML?

Porque el análisis de 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 solución de errores que tendrá que hacer. Por su propio bien, busque en Google "biblioteca XML" y aproveche el trabajo de otra persona.


Por lo general, las personas por defecto escriben patrones codiciosos, lo que a menudo lleva a un improviso. * Arrastrando grandes trozos de archivo en el mayor <foo>. * </foo> posible.


Uno 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 "barra", pueden venir en cualquier orden y tener cualquier número de otros. Las cosas entre ellos.