Une erreur que je vois des gens faire encore et encore est d'essayer d'analyser XML ou HTML avec une expression régulière. Voici quelques raisons pour lesquelles analyser XML et HTML est difficile:
Les gens veulent traiter un fichier comme une séquence de lignes, mais cela est valide:
<tag
attr="5"
/>
Les gens veulent traiter <ou <tag comme le début d'un tag, mais des trucs comme celui-ci existent à l'état sauvage:
<img src="imgtag.gif" alt="<img>" />
Les gens veulent souvent faire correspondre les balises de début aux balises de fin, mais XML et HTML permettent aux balises de se contenir (que les expressions régulières ne peuvent pas gérer du tout):
<span id="outer"><span id="inner">foo</span></span>
Les gens veulent souvent faire correspondre le contenu d'un document (comme le fameux problème «trouver tous les numéros de téléphone sur une page donnée»), mais les données peuvent être balisées (même si elles semblent être normales lors de leur affichage):
<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 balises mal formatées ou incomplètes:
<a href="foo">foo</a>
<!-- FIXME:
<a href="
-->
<a href="bar">bar</a>
De quels autres accrochages êtes-vous au courant?
Réponses:
Voici du XML valide et amusant pour vous:
Et ce petit paquet de joie est du HTML valide:
Sans parler de toute l'analyse spécifique au navigateur pour les constructions invalides.
Bonne chance opposant regex à cela!
EDIT (Jörg W Mittag): Voici un autre beau morceau de HTML 4.01 bien formé et valide:
la source
Réellement
n'est pas du HTML valide et n'est pas du XML non plus valide.
Ce n'est pas du XML valide car les «<» et «>» ne sont pas des caractères valides dans les chaînes d'attributs. Ils doivent être échappés à l'aide des entités XML correspondantes & lt; et & gt;
Ce n'est pas non plus du HTML valide car le court formulaire de fermeture n'est pas autorisé en HTML (mais est correct en XML et XHTML). La balise «img» est également une balise implicitement fermée selon la spécification HTML 4.01. Cela signifie que sa fermeture manuelle est en fait incorrecte et équivaut à la fermeture de toute autre balise deux fois.
La bonne version en HTML est
et la version correcte en XHTML et XML est
L'exemple suivant que vous avez donné est également invalide
Ce n'est pas non plus du HTML ou du XML valide. Le nom de la balise doit être juste derrière le '<', bien que les attributs et la fermeture '>' puissent être où ils veulent. Donc, le XML valide est en fait
Et voici une autre plus amusante: vous pouvez réellement choisir d'utiliser "ou 'comme caractère de citation de votre attribut
Toutes les autres raisons qui ont été publiées sont correctes, mais le plus gros problème avec l'analyse HTML est que les gens ne comprennent généralement pas correctement toutes les règles de syntaxe. Le fait que votre navigateur interprète votre groupe de balises comme HTML ne signifie pas que vous avez réellement écrit du HTML valide.
Edit: Et même stackoverflow.com est d'accord avec moi concernant la définition de valide et invalide. Votre XML / HTML invalide n'est pas mis en évidence, tandis que ma version corrigée l'est.
Fondamentalement, XML n'est pas conçu pour être analysé avec des expressions rationnelles. Mais il n'y a également aucune raison de le faire. Il existe de nombreux analyseurs XML pour chaque langue. Vous avez le choix entre les analyseurs SAX, les analyseurs DOM et les analyseurs Pull. Tous ces éléments sont garantis beaucoup plus rapides que l'analyse avec une expression rationnelle et vous pouvez ensuite utiliser des technologies intéressantes comme XPath ou XSLT sur l'arborescence DOM résultante.
Ma réponse est donc: non seulement l'analyse de XML avec des expressions régulières est difficile, mais c'est aussi une mauvaise idée. Utilisez simplement l'un des millions d'analyseurs XML existants et profitez de toutes les fonctionnalités avancées de XML.
Le HTML est tout simplement trop difficile pour même essayer d'analyser par vous-même. Premièrement, la syntaxe légale a de nombreuses petites subtilités que vous ne connaissez peut-être pas, et deuxièmement, le HTML à l'état sauvage n'est qu'une énorme pile puante (vous obtenez ma dérive). Il existe une variété de bibliothèques d'analyseurs laxistes qui font un bon travail pour gérer le HTML comme la soupe de balises, utilisez-les simplement.
la source
>
signe est parfaitement valide dans html stackoverflow.com/questions/94528/…J'ai écrit une entrée de blog entière sur ce sujet: Limitations des expressions régulières
Le nœud du problème est que HTML et XML sont des structures récursives qui nécessitent des mécanismes de comptage pour pouvoir analyser correctement. Un vrai regex n'est pas capable de compter. Vous devez avoir une grammaire sans contexte pour pouvoir compter.
Le paragraphe précédent est accompagné d'une légère mise en garde. Certaines implémentations d'expressions régulières supportent désormais l'idée de récursivité. Cependant, une fois que vous commencez à ajouter la récursivité dans vos expressions regex, vous étirez vraiment les limites et devez envisager un analyseur.
la source
Un problème qui ne figure pas dans votre liste est que les attributs peuvent apparaître dans n'importe quel ordre, donc si votre expression régulière recherche 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.
la source
Cela dépend de ce que vous entendez par "analyse". D'une manière générale, XML ne peut pas être analysé à l'aide de l'expression rationnelle car la grammaire XML n'est en aucun cas régulière. Pour le dire simplement, les expressions régulières ne peuvent pas compter (enfin, les expressions régulières Perl pourraient en fait être capables de compter les choses), vous ne pouvez donc pas équilibrer les balises d'ouverture-fermeture.
la source
Les gens font-ils une erreur en utilisant une expression régulière, ou est-ce simplement suffisant pour la tâche qu'ils essaient d'accomplir?
Je suis tout à fait d'accord que l'analyse de html et xml à l'aide d'une expression régulière n'est pas possible car d'autres personnes ont répondu.
Cependant, si votre exigence n'est pas d'analyser html / xml mais simplement d'obtenir un petit bit de données dans un bit "bien connu" de html / xml, alors peut-être qu'une expression régulière ou même une "sous-chaîne" encore plus simple est suffisante.
la source
Normalement, les gens écrivent par défaut des schémas gourmands, ce qui conduit souvent à un fichier non réfléchi. * Transformant de gros morceaux de fichier en <foo>. * </foo>.
la source
.*?<
, vous pouvez résoudre ce problème en utilisant une classe de caractères négative comme[^<]*<
. (Avertissement: évidemment ce n'est toujours pas infaillible, ce qui est le point de la question.)Je suis tenté de dire "ne réinventez pas la roue". Sauf que XML est un format vraiment très complexe. Alors peut-être devrais-je dire "ne réinventez pas le synchrotron".
Peut-être que le bon cliché commence "quand tout ce que vous avez est un marteau ..." Vous savez comment utiliser les expressions régulières, les expressions régulières sont bonnes pour l'analyse, alors pourquoi se donner la peine d'apprendre une bibliothèque d'analyse XML?
Parce que l'analyse XML est difficile . Tout effort que vous économiserez en n'ayant pas à apprendre à utiliser une bibliothèque d'analyse XML sera plus que compensé par la quantité de travail créatif et de correction de bogues que vous devrez faire. Pour vous, google "bibliothèque XML" et tirez parti du travail de quelqu'un d'autre.
la source
Je crois que ce classique contient les informations que vous recherchez. Vous pouvez trouver le point dans l'un des commentaires:
Quelques informations supplémentaires sur Wikipédia: Chomsky Hierarchy
la source
Je pense que les problèmes se résument à:
L'expression régulière est presque toujours incorrecte. Il existe des entrées légitimes auxquelles il ne correspondra pas correctement. Si vous travaillez assez dur, vous pouvez le rendre correct à 99% ou 99,999%, mais le rendre correct à 100% est presque impossible, ne serait-ce qu'en raison des choses étranges que XML permet en utilisant des entités.
Si l'expression régulière est incorrecte, même pour 0,00001% des entrées, vous avez un problème de sécurité, car quelqu'un peut découvrir la seule entrée qui cassera votre application.
Si l'expression régulière est suffisamment correcte pour couvrir 99,99% des cas, elle sera complètement illisible et impossible à maintenir.
Il est très probable qu'une expression régulière fonctionnera très mal sur des fichiers d'entrée de taille moyenne. Ma toute première rencontre avec XML a été de remplacer un script Perl qui analysait (incorrectement) les documents XML entrants avec un analyseur XML approprié, et nous avons non seulement remplacé 300 lignes de code illisible par 100 lignes que tout le monde pouvait comprendre, mais nous avons amélioré le temps de réponse des utilisateurs de 10 secondes à environ 0,1 seconde.
la source
Je ne suis pas d'accord. Si vous utilisez récursif dans regex, vous pouvez facilement trouver des balises d'ouverture et de fermeture.
Ici, j'ai montré un exemple de regex pour éviter les erreurs d'analyse des exemples dans le premier message.
la source
J'ai donné une réponse simplifiée à ce problème ici . Bien que cela ne représente pas la marque de 100%, j'explique comment c'est possible si vous êtes prêt à faire un travail de prétraitement.
la source