Je conviens que le bon outil pour analyser XML et en particulier HTML est un analyseur et non un moteur d'expression régulière. Cependant, comme d'autres l'ont souligné, l'utilisation d'une expression régulière est parfois plus rapide, plus facile et fait le travail si vous connaissez le format des données.
Microsoft a en fait une section des meilleures pratiques pour les expressions régulières dans le .NET Framework et parle spécifiquement de considérer [ing] la source d'entrée .
Les expressions régulières ont des limites, mais avez-vous pensé aux points suivants?
Le framework .NET est unique en ce qui concerne les expressions régulières en ce qu'il prend en charge l' équilibrage des définitions de groupe .
Pour cette raison, je crois que vous POUVEZ analyser XML en utilisant des expressions régulières. Notez cependant qu'il doit s'agir de XML valide (les navigateurs sont très indulgents envers HTML et autorisent une mauvaise syntaxe XML dans HTML ). Cela est possible car la "définition du groupe d'équilibrage" permettra au moteur d'expression régulière d'agir comme un PDA.
Citation de l'article 1 cité ci-dessus:
Moteur d'expression régulière .NET
Comme décrit ci-dessus, les constructions correctement équilibrées ne peuvent pas être décrites par une expression régulière. Cependant, le moteur d'expressions régulières .NET fournit quelques constructions qui permettent de reconnaître des constructions équilibrées.
(?<group>)
- pousse le résultat capturé sur la pile de capture avec le groupe de noms.
(?<-group>)
- affiche la capture la plus élevée avec le groupe de noms hors de la pile de capture.
(?(group)yes|no)
- correspond à la partie oui s'il existe un groupe avec le groupe de noms sinon ne correspond à aucune partie.
Ces constructions permettent à une expression régulière .NET d'émuler un PDA restreint en permettant essentiellement des versions simples des opérations de pile: push, pop et empty. Les opérations simples sont à peu près équivalentes à incrémenter, décrémenter et comparer à zéro respectivement. Cela permet au moteur d'expression régulière .NET de reconnaître un sous-ensemble des langages sans contexte, en particulier ceux qui ne nécessitent qu'un simple compteur. Cela permet à son tour aux expressions régulières .NET non traditionnelles de reconnaître les constructions individuelles correctement équilibrées.
Considérez l'expression régulière suivante:
(?=<ul\s+id="matchMe"\s+type="square"\s*>)
(?>
<!-- .*? --> |
<[^>]*/> |
(?<opentag><(?!/)[^>]*[^/]>) |
(?<-opentag></[^>]*[^/]>) |
[^<>]*
)*
(?(opentag)(?!))
Utilisez les drapeaux:
- Une seule ligne
- IgnorePatternWhitespace (pas nécessaire si vous réduisez l'expression régulière et supprimez tous les espaces)
- IgnoreCase (pas nécessaire)
Expression régulière expliquée (en ligne)
(?=<ul\s+id="matchMe"\s+type="square"\s*>) # match start with <ul id="matchMe"...
(?> # atomic group / don't backtrack (faster)
<!-- .*? --> | # match xml / html comment
<[^>]*/> | # self closing tag
(?<opentag><(?!/)[^>]*[^/]>) | # push opening xml tag
(?<-opentag></[^>]*[^/]>) | # pop closing xml tag
[^<>]* # something between tags
)* # match as many xml tags as possible
(?(opentag)(?!)) # ensure no 'opentag' groups are on stack
Vous pouvez l'essayer sur A Better .NET Regular Expression Tester .
J'ai utilisé la source d'échantillon de:
<html>
<body>
<div>
<br />
<ul id="matchMe" type="square">
<li>stuff...</li>
<li>more stuff</li>
<li>
<div>
<span>still more</span>
<ul>
<li>Another >ul<, oh my!</li>
<li>...</li>
</ul>
</div>
</li>
</ul>
</div>
</body>
</html>
Cela a trouvé le match:
<ul id="matchMe" type="square">
<li>stuff...</li>
<li>more stuff</li>
<li>
<div>
<span>still more</span>
<ul>
<li>Another >ul<, oh my!</li>
<li>...</li>
</ul>
</div>
</li>
</ul>
bien qu'il soit sorti comme ceci:
<ul id="matchMe" type="square"> <li>stuff...</li> <li>more stuff</li> <li> <div> <span>still more</span> <ul> <li>Another >ul<, oh my!</li> <li>...</li> </ul> </div> </li> </ul>
Enfin, j'ai vraiment apprécié l'article de Jeff Atwood: Parsing Html The Cthulhu Way . Assez drôle, il cite la réponse à cette question qui compte actuellement plus de 4k votes.