218 votes

Utiliser des expressions régulières pour analyser le HTML : pourquoi pas ?

Il semble que chaque question sur stackoverflow où l'auteur de la question utilise une expression rationnelle pour extraire des informations du HTML aura inévitablement une "réponse" qui dit de ne pas utiliser d'expression rationnelle pour analyser le HTML.

Pourquoi pas ? Je suis conscient qu'il existe des analyseurs HTML "réels", entre guillemets. Une belle soupe Je suis sûr qu'elles sont puissantes et utiles, mais si vous faites quelque chose de simple, rapide ou sale, pourquoi vous embêter à utiliser quelque chose de si compliqué alors que quelques instructions regex suffisent ?

De plus, y a-t-il quelque chose de fondamental que je ne comprends pas à propos des regex et qui en fait un mauvais choix pour l'analyse syntaxique en général ?

3 votes

Je pense que c'est une copie de stackoverflow.com/questions/133601

24 votes

Parce que seul Chuck Norris peut analyser le HTML avec des expressions rationnelles (comme expliqué dans ce fameux article de Zalgo) : stackoverflow.com/questions/1732348/ ).

1 votes

Cette question m'a incité à en poser une autre qui est en quelque sorte liée. Au cas où vous seriez intéressé : Pourquoi il n'est pas possible d'utiliser les regex pour analyser le HTML/XML : une explication formelle en termes simples.

223voto

Johannes Weiß Points 19013

L'analyse complète du HTML n'est pas possible avec les expressions régulières, car elle dépend de la correspondance entre les balises d'ouverture et de fermeture, ce qui n'est pas possible avec les regexps.

Les expressions régulières ne peuvent correspondre qu'à langues régulières mais le HTML est un langage sans contexte et no un langage régulier (comme @StefanPochmann l'a fait remarquer, les langages réguliers sont également sans contexte, donc sans contexte ne signifie pas nécessairement non régulier). La seule chose que vous pouvez faire avec les regexps sur le HTML est une heuristique, mais cela ne fonctionnera pas pour toutes les conditions. Il devrait être possible de présenter un fichier HTML qui ne sera pas reconnu par n'importe quelle expression régulière.

26 votes

La meilleure réponse jusqu'à présent. S'il ne peut correspondre qu'à des grammaires régulières, alors nous aurions besoin d'une regexp infiniment grande pour analyser une grammaire sans contexte comme le HTML. J'aime quand ces choses ont des réponses théoriques claires.

2 votes

J'ai supposé que nous discutions de regex de type Perl alors qu'il ne s'agit pas vraiment d'expressions régulières.

0 votes

Qu'est-ce qui fait que les expressions régulières de type Perl ne sont pas de véritables expressions régulières ?

37voto

kmkaplan Points 10338

Pour une utilisation rapide, un regexp fera l'affaire. Mais la chose fondamentale à savoir est qu'il est impossible pour construire un regexp qui correctement analyser le HTML.

La raison en est que les regexps ne peuvent pas gérer les expressions arbitrairement imbriquées. Voir Les expressions régulières peuvent-elles être utilisées pour faire correspondre des motifs imbriqués ?

1 votes

Certaines librairies regex peuvent faire des expressions régulières récursives (ce qui en fait des expressions non régulières :)

27voto

Andy Lester Points 34051

(De http://htmlparsing.com/regexes )

Say you've got a file of HTML where you're trying to extract URLs from <img> tags.

<img src="http://example.com/whatever.jpg">

Donc vous écrivez une regex comme ceci en Perl :

if ( $html =~ /<img src="(.+)"/ ) {
    $url = $1;
}

Dans ce cas, $url contiendra en effet http://example.com/whatever.jpg . Mais que se passe-t-il quand vous commencez à avoir du HTML comme ça :

<img src='http://example.com/whatever.jpg'>

ou

<img src=http://example.com/whatever.jpg>

ou

<img border=0 src="http://example.com/whatever.jpg">

ou

<img
    src="http://example.com/whatever.jpg">

ou vous commencez à obtenir des faux positifs de

<!-- // commented out
<img src="http://example.com/outdated.png">
-->

Cela semble si simple, et cela peut l'être pour un fichier unique et immuable, mais pour tout ce que vous allez faire sur des données HTML arbitraires, les regex ne sont qu'une recette pour de futurs maux de tête.

4 votes

Cela semble être la vraie réponse - bien qu'il soit probablement possible de parser du HTML arbitraire avec des regex puisque les regex d'aujourd'hui sont plus que des automates finis, afin de parser du HTML arbitraire et pas seulement une page concrète, vous devez réimplémenter un parseur HTML en regexp et les regex deviennent sûrement 1000 fois illisibles.

1 votes

Hey Andy, j'ai pris le temps de trouver une expression qui soutient les cas que vous avez mentionnés. stackoverflow.com/a/40095824/1204332 Faites-moi savoir ce que vous en pensez ! :)

2 votes

Le raisonnement dans cette réponse est chemin dépassée, et s'applique encore moins aujourd'hui qu'à l'origine (ce qui n'était pas le cas, je pense). (Citation de l'OP : "si vous faites juste quelque chose de simple, rapide ou sale...").

16voto

Hank Gay Points 36173

Deux raisons rapides :

  • écrire une regex qui peut résister à une entrée malveillante est difficile ; bien plus difficile que d'utiliser un outil préconstruit
  • écrire une regex qui peut fonctionner avec le balisage ridicule avec lequel vous serez inévitablement coincé est difficile ; bien plus difficile que d'utiliser un outil pré-construit

En ce qui concerne l'adéquation des regex pour l'analyse syntaxique en général : elles ne sont pas adaptées. Avez-vous déjà vu les types de regex dont vous auriez besoin pour analyser la plupart des langues ?

2 votes

Wow ? Un downvote après 2+ ans ? Au cas où quelqu'un se demanderait, je n'ai pas dit "Parce que c'est théoriquement impossible" parce que la question demandait clairement "vite fait bien fait", et non "correct". Le PO a clairement déjà lu des réponses qui couvraient le territoire théoriquement impossible et n'était toujours pas satisfait.

1 votes

Avoir un upvote après 5+ ans :) Quant à la raison pour laquelle vous avez reçu un downvote, je ne suis pas qualifié pour le dire, mais personnellement, j'aurais aimé voir des exemples ou une explication plutôt que la question rhétorique finale.

3 votes

Essentiellement, toute analyse html rapide et sale effectuée dans les produits de livraison ou les outils internes finit par constituer une faille de sécurité béante ou un bogue en attente. Cette pratique doit être découragée avec enthousiasme. Si l'on peut utiliser une regex, on peut utiliser un analyseur html correct.

16voto

Vatine Points 8884

En ce qui concerne l'analyse syntaxique, les expressions régulières peuvent être utiles dans l'étape d'"analyse lexicale" (lexer), où l'entrée est décomposée en tokens. Elles sont moins utiles dans la phase de "construction d'un arbre d'analyse".

Pour un analyseur HTML, je m'attendrais à ce qu'il n'accepte que du HTML bien formé, ce qui exige des capacités autres que celles d'une expression régulière (elle ne peut pas "compter" et s'assurer qu'un nombre donné d'éléments d'ouverture est équilibré par le même nombre d'éléments de fermeture).

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