416 votes

Pouvez-vous donner quelques exemples de pourquoi il est difficile d'analyser XML et HTML avec une regex?

Une erreur que je vois les gens faire de plus et plus de nouveau est en train d'essayer de parser XML ou HTML avec une regex. Voici quelques-unes des raisons pour l'analyse de XML et HTML est dur:

Les gens veulent traiter un fichier comme une séquence de lignes, mais c'est valable:

<tag
attr="5"
/>

Les gens veulent traiter < ou <tag comme le début d'une balise, mais des trucs comme cela existe dans la nature:

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

Souvent, les gens veulent à fonction étiquettes pour étiquettes de fin, mais XML et HTML balises permettent de contenir eux-mêmes (qui traditionnel regexes ne peut pas gérer du tout):

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

Souvent, les gens veulent match contre le contenu d'un document (comme le célèbre "trouver tous les numéros de téléphone sur une page donnée du problème"), mais les données peuvent être marqués (même si il semble être normal vu):

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

Les commentaires peuvent contenir des mal formaté ou incomplète tags:

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

Quels sont les autres problèmes êtes-vous au courant?

270voto

bobince Points 270740

Voici un code XML amusant et amusant pour vous:

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

Et ce petit paquet de joie est valide HTML:

 <!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>
 

Sans parler de tout l'analyse spécifique au navigateur pour les constructions invalides.

Bonne chance piquer regex contre ça!

EDIT (Jörg W Mittag): Voici un autre bon morceau de HTML 4.01 bien formé et valide:

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd"> 
<HTML/
  <HEAD/
    <TITLE/>/
    <P/>
 

73voto

LordOfThePigs Points 3853

En fait

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

n'est pas valide en HTML, et n'est pas valide XML.

Il n'est pas valide XML, car les " < " et " > " ne sont pas des caractères valides à l'intérieur de l'attribut cordes. Ils ont besoin d'être échappés à l'aide du correspondant entités XML &lt; et &gt;

Il n'est pas valide HTML soit en raison de la court de fermeture du formulaire n'est pas autorisé dans le HTML (mais est correcte en XML et XHTML). Le 'img' tag est aussi un fermé implicitement étiquette conformément à la spécification HTML 4.01. Cela signifie que manuellement la fermeture est en fait mal, et est équivalent à la clôture de toute autre tag à deux reprises.

La version correcte dans le HTML est

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

et la version correcte en XHTML et XML est

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

L'exemple suivant vous a donné n'est pas valide

<
tag
attr="5"
/>

Ce n'est pas valide en HTML ou XML. Le nom de la balise doit être juste derrière le '<', bien que les attributs et la fermeture " > " est peut-être là où ils le désirent. De sorte que le XML valide est en fait

<tag
attr="5"
/>

Et voici un autre funky: vous pouvez choisir d'utiliser soit " ou " comme attribut citant caractère

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

Toutes les autres raisons qui ont été affichées sont correctes, mais le plus gros problème avec l'analyse HTML est que d'habitude les gens ne comprennent pas toutes les règles de syntaxe correctement. Le fait que votre navigateur interprète votre tagsoup que HTML ne signifie pas que vous avez écrit dans un code HTML valide.

Edit: Et même stackoverflow.com d'accord avec moi au sujet de la définition de valides et non valides. Votre invalid XML/HTML n'est pas mis en évidence, alors que ma version corrigée est.

Fondamentalement, XML n'est pas fait pour être analysé avec les expressions régulières. Mais il n'y a également aucune raison de le faire. Il y a beaucoup, beaucoup de parseurs XML pour chaque langue. Vous avez le choix entre les parseurs SAX, DOM analyseurs et de Tirer des analyseurs. Tous ces produits sont garantis d'être beaucoup plus rapide que l'analyse avec une regexp et vous pouvez ensuite utiliser cool technologies comme XPath ou XSLT sur l'arborescence DOM.

Ma réponse est donc: non seulement l'analyse de XML avec les expressions régulières dur, mais c'est aussi une mauvaise idée. Il suffit d'utiliser une des millions de existant parseurs XML, et de profiter de toutes les fonctionnalités avancées du langage XML.

HTML est tout simplement trop difficile à même d'essayer d'analyser sur votre propre. D'abord, le juridique, la syntaxe a beaucoup de petites subtilités que vous pourriez ne pas être conscient de, et la deuxième, HTML dans la nature est juste un énorme tas puant de (vous obtenez ma dérive). Il existe une variété de lax analyseur de bibliothèques qui font un bon travail lors de la manipulation de code HTML comme la soupe de tags, il suffit d'utiliser ces.

62voto

JaredPar Points 333733

J'ai écrit toute une entrée de blog sur ce sujet: Expression Régulière Limitations

Le nœud de la question est que HTML et XML sont des structures récursives qui exige mécanismes de comptage afin d'analyser correctement. Un vrai regex n'est pas capable de comptage. Vous devez disposer d'une grammaire sans contexte afin de compter.

Le paragraphe précédent est livré avec une légère mise en garde. Certains regex implémentations maintenant l'appui de l'idée de récursivité. Cependant, une fois que vous commencez à ajouter de la récursion dans vos expressions régulières, vous êtes vraiment repoussant les limites et devrait envisager d'un analyseur.

22voto

AmbroseChapel Points 4971

Un gotcha pas sur votre liste est que les attributs peuvent apparaître dans n'importe quel ordre, donc si votre regex cherche un lien avec le href "foo" et la classe "bar", ils peuvent venir dans n'importe quel ordre, et avoir un certain nombre d'autres les choses entre eux.

18voto

Anton Gogolev Points 59794

Cela dépend de ce que vous entendez par "analyse". D'une manière générale, XML ne peut pas être analysé en utilisant regex car la grammaire XML n'est en aucun cas régulière. Pour le dire simplement, les expressions rationnelles ne peuvent pas compter (bien, les expressions rationnelles de Perl pourraient réellement être en mesure de compter les choses) de sorte que vous ne pouvez pas équilibrer les balises open-close.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X