Les expressions régulières sont un outil puissant dans l'arsenal du programmeur, mais - dans certains cas, elles ne sont pas le meilleur choix, voire carrément nuisibles.
L'exemple simple # 1 est l'analyse HTML avec regexp - une voie connue vers de nombreux bogues. Probablement, cela attribue également à analyse en général.
Mais, existe-t-il d'autres domaines clairement interdits pour les expressions régulières?
ps: " La question que vous posez semble subjective et est susceptible d'être fermée." - donc, je tiens à souligner que je suis intéressé par des exemples où l'utilisation de regexps est connue pour causer problèmes.
N'utilisez pas d'expressions régulières:
Cela ne se limite pas à HTML . Un simple XML valide ne peut pas être raisonnablement analysé avec une expression régulière, même si vous connaissez le schéma et que vous savez qu'il ne changera jamais.
N'essayez pas, par exemple, analyser le code source C # . Analysez-le à la place, pour obtenir une arborescence significative ou les jetons.
Et si vous devez rechercher une lettre, petite ou majuscule? Si vous aimez les expressions régulières, vous les utiliserez. Mais n'est-il pas plus facile/plus rapide/lisible d'utiliser deux recherches l'une après l'autre? Il est probable que dans la plupart des langues, vous obtiendrez de meilleures performances et rendrez votre code plus lisible.
Par exemple, l'exemple de code dans la réponse d'Ingo est un bon exemple lorsque vous ne devez pas utiliser d'expressions régulières. Recherchez simplement foo
, puis bar
.
Un bon exemple est un filtre d'obscénité. Non seulement c'est ne mauvaise idée en général pour l'implémenter, mais vous pouvez être tenté de le faire en utilisant des expressions régulières, et vous le ferez mal. Il y a beaucoup de façons dont un humain peut écrire un mot, un nombre, une phrase et sera compris par un autre humain, mais pas votre expression régulière. Ainsi, au lieu d'attraper une véritable obscénité, votre expression régulière passera son temps à blesser d'autres utilisateurs.
Par exemple, ne validez pas une adresse e-mail via une expression régulière. Dans la plupart des cas, vous le ferez mal. Dans un cas rare, vous le ferez correctement et terminez avec une horreur de codage de 6 343 caractères .
Sans les bons outils, vous ferez des erreurs. Et vous les remarquerez au dernier moment, ou peut-être jamais. Si vous ne vous souciez pas du code propre, vous écrirez une chaîne de vingt lignes sans commentaires, sans espaces, sans retour à la ligne.
Sérieusement, si je prends votre code et que je dois le réviser ou le modifier, je ne veux pas passer une semaine à essayer de comprendre une longue chaîne de vingt lignes de symboles.
La chose la plus importante: lorsque la langue que vous analysez n'est pas un langage normal .
Le HTML n'est pas un langage régulier et l'analyse syntaxique avec une expression régulière n'est pas possible (non seulement difficile ou un chemin vers le code buggy).
Sur stackoverflow, on voit souvent des gens demander des expressions rationnelles qui découvrent si une chaîne donnée contient pas ceci ou cela. C'est, à mon humble avis, inverser le but de l'expression régulière. Même s'il existe une solution (en utilisant des assertions de lookbehind négatives ou de telles choses), il est souvent préférable d'utiliser l'expression régulière pour ce qu'elle a été faite et de gérer le cas négatif avec la logique du programme.
Exemple:
# bad
if (/complicated regex that assures the string does NOT conatin foo|bar/) {
# do something
}
# appropriate
if (/foo|bar/) {
# error handling
} else {
# do something
}
Deux cas:
La plupart des langages fournissent une fonction simple comme INSTR pour déterminer si une chaîne est un sous-ensemble d'une autre. Si c'est ce que vous voulez faire, utilisez la fonction plus simple. N'écrivez pas votre propre expression régulière.
Si une bibliothèque est disponible pour effectuer une manipulation de chaîne complexe, utilisez-la plutôt que d'écrire votre propre expression régulière.
Les expressions régulières ne peuvent pas identifier structures récursives. C'est la limitation fondamentale.
Prenez JSON - c'est un format assez simple, mais comme un objet peut contenir d'autres objets en tant que valeurs membres (arbitrairement profondes), la syntaxe est récursive et ne peut pas être analysée par une expression régulière. D'autre part, CSV peut être analysé par des expressions rationnelles car il ne contient aucune structure récursive.
En bref, les expressions régulières ne permettent pas au modèle de se référer à lui-même. Vous ne pouvez pas dire: à ce stade de la syntaxe, faites de nouveau correspondre à l'ensemble du modèle. En d'autres termes, les expressions régulières ne correspondent que de manière linéaire, elles ne contiennent pas de pile qui leur permettrait de garder une trace de la profondeur d'un motif imbriqué.
Notez que cela n'a rien à voir avec la complexité ou la complication du format. Les expressions S sont vraiment très simples, mais ne peuvent pas être analysées avec une expression régulière. CSS2 d'autre part est un langage assez complexe, mais ne contient pas de structures récursives et à cet effet peut être analysé avec une expression régulière. (Bien que ce ne soit pas vrai pour CSS3 en raison des expressions CSS, qui ont une syntaxe récursive.)
Ce n'est donc pas parce qu'il est laid ou complexe ou sujet aux erreurs d'analyser le HTML en utilisant uniquement l'expression régulière. C'est que c'est simplement pas possible.
Si vous avez besoin d'analyser un format qui contient des structures récursives, vous devez au moins compléter l'utilisation d'expressions régulières avec une pile pour garder une trace du niveau des structures récursives. C'est généralement ainsi que fonctionne un analyseur. Les expressions régulières sont utilisées pour reconnaître les parties "linéaires", tandis que le code personnalisé en dehors de l'expression régulière est utilisé pour garder une trace des structures imbriquées.
Généralement, l'analyse comme celle-ci est divisée en phases distinctes. La tokenisation est la première phase où les expressions régulières sont utilisées pour diviser l'entrée en une séquence de "jetons" comme les mots, la ponctuation, les crochets, etc. L'analyse est la phase suivante où ces jetons sont analysés dans une structure hiérarchique, un arbre de syntaxe.
Ainsi, lorsque vous entendez que HTML ou C # ne peut pas être analysé par des expressions régulières, sachez que les expressions régulières sont toujours une partie critique des analyseurs. Vous ne pouvez simplement pas analyser un tel langage en utilisant uniquement des expressions régulières et aucun code d'aide.