Pourquoi les expressions régulières sont-elles si controversées? [fermé]


212

Lors de l'exploration des expressions régulières (autrement connues sous le nom de RegEx-es), de nombreuses personnes semblent considérer les expressions régulières comme le Saint Graal. Quelque chose qui semble si compliqué - doit juste être la réponse à toute question. Ils ont tendance à penser que chaque problème peut être résolu à l'aide d'expressions régulières.

D'un autre côté, il y a aussi beaucoup de gens qui essaient à tout prix d'éviter les expressions régulières. Ils essaient de trouver un moyen de contourner les expressions régulières et acceptent un codage supplémentaire juste pour le plaisir, même si une expression régulière serait une solution plus compacte.

Pourquoi les expressions régulières sont-elles si controversées? Y a-t-il des malentendus répandus sur leur fonctionnement? Ou pourrait-on penser que les expressions régulières sont généralement lentes?


9
s'il s'agit d'une discussion, ne devrait-elle pas être close? mais je vois une vraie question là-dedans alors peut-être que la balise de discussion n'appartient pas?
RCIX

6
Sans blague. Vous en parlez et les gens commencent à devenir fous ici.
Ryan Florence

1
Belle observation et formulation dans la question!
imz - Ivan Zakharyaschev


La question est basée sur l'opinion, la règle devrait également s'appliquer ici (ou la question doit être modifiée pour viser une réponse précise). Cela dit, je suppose que les expressions rationnelles controversées proviennent de la non-précision des tutoriels et des manuels à ce sujet. La plupart du temps sinon toutes les informations sont mélangées et en plus on ne nous donne pas toutes les caractéristiques. Ajoutez à cette langue une mauvaise utilisation, vous finissez par apprendre quelque chose pour remarquer sur la route que cela peut signifier autre chose. Et enfin, les caractères spéciaux regex ne sont pas limités à une seule signification qui ajoute plus de confusion.
intika

Réponses:


136

Je ne pense pas que les gens s'opposent aux expressions régulières parce qu'ils sont lents, mais plutôt parce qu'ils sont difficiles à lire et à écrire, ainsi que difficiles à comprendre. Bien qu'il existe certaines situations où les expressions régulières fournissent une solution efficace et compacte au problème, elles sont parfois mises en boîte dans des situations où il est préférable d'utiliser à la place une section de code facile à lire et maintenable.


2
Et oui, les expressions régulières peuvent être extrêmement extrêmement lentes par rapport à l'utilisation de fonctions simples. Et pas seulement lent, mais les performances du moteur regex peuvent être totalement imprévisibles face à des entrées arbitraires (fournies par l'utilisateur).
Pacerier

1
Si vous savez comment fonctionne regex, ce n'est pas du tout un problème.
Shiplu Mokaddim

8
@pacerier, ce ne sont pas des schémas lents , ce sont des moteurs lents . La plupart des moteurs d' expression régulière (modernes) ne conviennent pas aux modèles complexes (par exemple, plusieurs |ou .*), car ils utilisent une machine de pile et un retour arrière. C'est pourquoi vous devez régler soigneusement vos expressions régulières en Perl, Java, Python, Ruby… Les moteurs d'expressions régulières à l'ancienne (dans grep, par exemple) compilent d'abord le modèle dans un DFA. Par la suite, la complexité du modèle est largement hors de propos. Je viens d'utiliser Java et grep pour le même texte et modèle: 22min vs 2s. Voici la science: swtch.com/~rsc/regexp/regexp1.html
hagello

122

Rendre les regexes maintenables

Une avancée majeure vers la démystification des modèles précédemment appelés «expressions régulières» est le /xdrapeau regex de Perl - parfois écrit (?x)lorsqu'il est intégré - qui permet les espaces blancs (saut de ligne, indentation) et les commentaires. Cela améliore considérablement la lisibilité et donc la maintenabilité. L'espace blanc permet un découpage cognitif, de sorte que vous pouvez voir quels groupes avec quoi.

Les modèles modernes prennent également en charge à la fois les références numériques relativement numérotées et nommées. Cela signifie que vous n'avez plus besoin de compter les groupes de capture pour comprendre que vous avez besoin de $4ou \7. Cela aide lors de la création de motifs qui peuvent être inclus dans d'autres motifs.

Voici un exemple de groupe de capture relativement numéroté:

$ dupword = qr {\ b (?: (\ w +) (?: \ s + \ g {-1}) +) \ b} xi;
$ quoted = qr {(["']) $ dupword \ 1} x;

Et voici un exemple de l'approche supérieure des captures nommées:

$dupword = qr{ \b (?: (?<word> \w+ ) (?: \s+ \k<word> )+ ) \b }xi;
$quoted  = qr{ (?<quote> ["'] ) $dupword  \g{quote} }x;

Regexes grammaticaux

Mieux encore , ces captures nommées peuvent être placées dans un (?(DEFINE)...)bloc, afin que vous puissiez séparer la déclaration de l'exécution des éléments nommés individuels de vos modèles. Cela les fait agir plutôt comme des sous-programmes dans le modèle.
Un bon exemple de ce genre de «regex grammatical» peut être trouvé dans cette réponse et celle-ci . Celles-ci ressemblent beaucoup plus à une déclaration grammaticale.

Comme ce dernier vous le rappelle:

… Assurez-vous de ne jamais écrire de modèles de bruit de ligne. Vous n'êtes pas obligé, et vous ne devriez pas. Aucun langage de programmation ne peut être maintenu et interdit les espaces blancs, les commentaires, les sous-programmes ou les identificateurs alphanumériques. Utilisez donc toutes ces choses dans vos modèles.

Cela ne peut pas être trop souligné. Bien sûr, si vous n'utilisez pas ces choses dans vos modèles, vous créerez souvent un cauchemar. Mais si vous les utilisez, vous n'en avez pas besoin.

Voici un autre exemple d'un modèle grammatical moderne, celui-ci pour l'analyse RFC 5322: utilisez 5.10.0;

$rfc5322 = qr{

   (?(DEFINE)

     (?<address>         (?&mailbox) | (?&group))
     (?<mailbox>         (?&name_addr) | (?&addr_spec))
     (?<name_addr>       (?&display_name)? (?&angle_addr))
     (?<angle_addr>      (?&CFWS)? < (?&addr_spec) > (?&CFWS)?)
     (?<group>           (?&display_name) : (?:(?&mailbox_list) | (?&CFWS))? ; (?&CFWS)?)
     (?<display_name>    (?&phrase))
     (?<mailbox_list>    (?&mailbox) (?: , (?&mailbox))*)

     (?<addr_spec>       (?&local_part) \@ (?&domain))
     (?<local_part>      (?&dot_atom) | (?&quoted_string))
     (?<domain>          (?&dot_atom) | (?&domain_literal))
     (?<domain_literal>  (?&CFWS)? \[ (?: (?&FWS)? (?&dcontent))* (?&FWS)?
                                   \] (?&CFWS)?)
     (?<dcontent>        (?&dtext) | (?&quoted_pair))
     (?<dtext>           (?&NO_WS_CTL) | [\x21-\x5a\x5e-\x7e])

     (?<atext>           (?&ALPHA) | (?&DIGIT) | [!#\$%&'*+-/=?^_`{|}~])
     (?<atom>            (?&CFWS)? (?&atext)+ (?&CFWS)?)
     (?<dot_atom>        (?&CFWS)? (?&dot_atom_text) (?&CFWS)?)
     (?<dot_atom_text>   (?&atext)+ (?: \. (?&atext)+)*)

     (?<text>            [\x01-\x09\x0b\x0c\x0e-\x7f])
     (?<quoted_pair>     \\ (?&text))

     (?<qtext>           (?&NO_WS_CTL) | [\x21\x23-\x5b\x5d-\x7e])
     (?<qcontent>        (?&qtext) | (?&quoted_pair))
     (?<quoted_string>   (?&CFWS)? (?&DQUOTE) (?:(?&FWS)? (?&qcontent))*
                          (?&FWS)? (?&DQUOTE) (?&CFWS)?)

     (?<word>            (?&atom) | (?&quoted_string))
     (?<phrase>          (?&word)+)

     # Folding white space
     (?<FWS>             (?: (?&WSP)* (?&CRLF))? (?&WSP)+)
     (?<ctext>           (?&NO_WS_CTL) | [\x21-\x27\x2a-\x5b\x5d-\x7e])
     (?<ccontent>        (?&ctext) | (?&quoted_pair) | (?&comment))
     (?<comment>         \( (?: (?&FWS)? (?&ccontent))* (?&FWS)? \) )
     (?<CFWS>            (?: (?&FWS)? (?&comment))*
                         (?: (?:(?&FWS)? (?&comment)) | (?&FWS)))

     # No whitespace control
     (?<NO_WS_CTL>       [\x01-\x08\x0b\x0c\x0e-\x1f\x7f])

     (?<ALPHA>           [A-Za-z])
     (?<DIGIT>           [0-9])
     (?<CRLF>            \x0d \x0a)
     (?<DQUOTE>          ")
     (?<WSP>             [\x20\x09])
   )

   (?&address)

}x;

N'est-ce pas remarquable - et splendide? Vous pouvez prendre une grammaire de style BNF et la traduire directement en code sans perdre sa structure fondamentale!

Si les modèles grammaticaux modernes ne vous suffisent toujours pas, alors le brillant Regexp::Grammarsmodule de Damian Conway offre une syntaxe encore plus propre, avec un débogage supérieur également. Voici le même code pour analyser la refonte RFC 5322 dans un modèle de ce module:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;
use Data::Dumper "Dumper";

my $rfc5322 = do {
    use Regexp::Grammars;    # ...the magic is lexically scoped
    qr{

    # Keep the big stick handy, just in case...
    # <debug:on>

    # Match this...
    <address>

    # As defined by these...
    <token: address>         <mailbox> | <group>
    <token: mailbox>         <name_addr> | <addr_spec>
    <token: name_addr>       <display_name>? <angle_addr>
    <token: angle_addr>      <CFWS>? \< <addr_spec> \> <CFWS>?
    <token: group>           <display_name> : (?:<mailbox_list> | <CFWS>)? ; <CFWS>?
    <token: display_name>    <phrase>
    <token: mailbox_list>    <[mailbox]> ** (,)

    <token: addr_spec>       <local_part> \@ <domain>
    <token: local_part>      <dot_atom> | <quoted_string>
    <token: domain>          <dot_atom> | <domain_literal>
    <token: domain_literal>  <CFWS>? \[ (?: <FWS>? <[dcontent]>)* <FWS>?

    <token: dcontent>        <dtext> | <quoted_pair>
    <token: dtext>           <.NO_WS_CTL> | [\x21-\x5a\x5e-\x7e]

    <token: atext>           <.ALPHA> | <.DIGIT> | [!#\$%&'*+-/=?^_`{|}~]
    <token: atom>            <.CFWS>? <.atext>+ <.CFWS>?
    <token: dot_atom>        <.CFWS>? <.dot_atom_text> <.CFWS>?
    <token: dot_atom>        <.CFWS>? <.dot_atom_text> <.CFWS>?
    <token: dot_atom_text>   <.atext>+ (?: \. <.atext>+)*

    <token: text>            [\x01-\x09\x0b\x0c\x0e-\x7f]
    <token: quoted_pair>     \\ <.text>

    <token: qtext>           <.NO_WS_CTL> | [\x21\x23-\x5b\x5d-\x7e]
    <token: qcontent>        <.qtext> | <.quoted_pair>
    <token: quoted_string>   <.CFWS>? <.DQUOTE> (?:<.FWS>? <.qcontent>)*
                             <.FWS>? <.DQUOTE> <.CFWS>?

    <token: word>            <.atom> | <.quoted_string>
    <token: phrase>          <.word>+

    # Folding white space
    <token: FWS>             (?: <.WSP>* <.CRLF>)? <.WSP>+
    <token: ctext>           <.NO_WS_CTL> | [\x21-\x27\x2a-\x5b\x5d-\x7e]
    <token: ccontent>        <.ctext> | <.quoted_pair> | <.comment>
    <token: comment>         \( (?: <.FWS>? <.ccontent>)* <.FWS>? \)
    <token: CFWS>            (?: <.FWS>? <.comment>)*
                             (?: (?:<.FWS>? <.comment>) | <.FWS>)

    # No whitespace control
    <token: NO_WS_CTL>       [\x01-\x08\x0b\x0c\x0e-\x1f\x7f]

    <token: ALPHA>           [A-Za-z]
    <token: DIGIT>           [0-9]
    <token: CRLF>            \x0d \x0a
    <token: DQUOTE>          "
    <token: WSP>             [\x20\x09]

    }x;

};


while (my $input = <>) {
    if ($input =~ $rfc5322) {
        say Dumper \%/;       # ...the parse tree of any successful match
                              # appears in this punctuation variable
    }
}

Il y a beaucoup de bonnes choses dans la page de manuel de perlre , mais ces améliorations spectaculaires dans les fonctionnalités de conception regex fondamentales ne sont en aucun cas limitées à Perl seul. En effet, la page de manuel pcrepattern peut être plus facile à lire et couvre le même territoire.

Les modèles modernes n'ont presque rien en commun avec les choses primitives qui vous ont été enseignées dans votre classe d'automates finis.


9
OUI! OUI! Enfin, quelqu'un montre un excellent exemple de la façon dont les expressions rationnelles peuvent être lisibles avec le modificateur x. Je ne peux pas croire combien peu de gens savent qu'il existe, et encore moins l'utiliser.
Shabbyrobe

1
@Shabbyrobe: Ce n'est pas seulement /x. C'est l'utilisation des expressions rationnelles grammaticalement, avec (?&name)des sous-programmes regex internes, qui fait vraiment briller.
tchrist

+1 Vous apprenez toujours quelque chose de nouveau. Je ne savais pas que PCRE avait une "fausse" condition pour les définitions.
NikiC

5
Python a également un re.VERBOSEdrapeau.
Escargot mécanique

3
Gunna, allez-y et dites que je suis toujours étonné de voir jusqu'où les gens vont aller pour rendre les regex utilisables.
Slater Victoroff

68

Les regex sont un excellent outil, mais les gens pensent "Hé, quel excellent outil, je vais l'utiliser pour faire X!" où X est quelque chose pour lequel un autre outil est préférable (généralement un analyseur). C'est la norme à l'aide d'un marteau où vous avez besoin d'un problème de tournevis.


4
N'oubliez pas que la plupart des analyseurs - analyseurs flexibles - utilisent toujours des expressions régulières pour analyser leur contenu :-)
Jasper Bekkers

62
Dire que les analyseurs utilisent des expressions régulières revient à dire que les analyseurs utilisent des instructions d'affectation. Cela ne veut rien dire tant que vous ne voyez pas comment ils sont utilisés.
Chas. Owens

24
Utiliser un RegEx quand un analyseur est meilleur est ennuyeux. L'utilisation d'un RegEx lorsque la fonction de recherche ou de remplacement de chaîne standard du langage fonctionne (et en temps linéaire généralement) est tout simplement impardonnable.
jmucchiello

1
D'accord, car un RegEx doit être un cric de tous les métiers, il traite les frais généraux est énorme. Tout simplement parce que l'utilisation d'un moteur RegEx semble facile ne signifie pas que c'est une meilleure solution par rapport à un analyseur itératif (seuil dépendant du développeur). Un de mes exemples préférés split($pattern,$string)contre vs de PHP explode($delimiter,$string)- heureusement, le premier est déprécié, mais beaucoup de code a utilisé le premier alors qu'il n'avait besoin que de la puissance du dernier. D'accord, les RegEx fournissent un outil facile pour faire certaines choses, mais à moins que vous n'ayez besoin de la pleine puissance des expressions régulières, ils
Rudu

4
Les analyseurs lexicaux peuvent en effet utiliser des expressions rationnelles. Ils sont également appelés tokenizers, mais ils ne sont pas des analyseurs syntaxiques (ou des analyseurs). Pour lire une chaîne suffisamment compliquée, un tokenizer doit être utilisé pour lire la chaîne en tant que tokens (peut-être avec des expressions rationnelles, peut-être pas, selon le tokenizer). Ces jetons doivent ensuite être transmis à l'analyseur, qui les traitera avec des règles de grammaire, qui ne sont certainement pas des expressions rationnelles.
Axel

53

Presque tous ceux que je connais qui utilisent régulièrement des expressions régulières (jeu de mots) viennent d'un arrière-plan Unix où ils utilisent des outils qui traitent les RE comme des constructions de programmation de première classe, telles que grep, sed, awk et Perl. Comme il n'y a presque pas de surcharge syntaxique pour utiliser une expression régulière, leur productivité augmente considérablement lorsqu'ils le font.

En revanche, les programmeurs qui utilisent des langages dans lesquels les RE sont une bibliothèque externe ont tendance à ne pas considérer ce que les expressions régulières peuvent apporter à la table. Le "temps-coût" du programmeur est si élevé que soit a) les RE ne sont jamais apparus dans le cadre de leur formation, soit b) ils ne "pensent" pas en termes de RE et préfèrent se rabattre sur des schémas plus familiers.


11
Oui, je n'ai jamais pardonné à Python d'avoir rendu la syntaxe regex verbeuse en utilisant une bibliothèque. Je pense que c'est la pureté sur la raison.
slikts

7
Je viens d'un arrière-plan Unix, j'ai utilisé des charges sed, awk et perl, et bien sûr j'ai fait beaucoup de grepping, mais sachez que lorsque j'utilise une expression régulière, c'est un hack en écriture seule que je déteste maintenir. C'est bon pour les scripts shell / ponctuels, mais pour le vrai travail, pour tout ce qui n'est pas juste pour récupérer des données à sauvegarder maintenant, j'utilise maintenant un tokenizer / lexer / parser approprié avec une syntaxe claire. Mon préféré fait tout / tout, proprement + peut s'auto-optimiser. J'ai appris à la dure, et pendant de nombreuses années, qu'un peu d'autodiscipline au début signifie moins d'efforts plus tard. Un regex est un moment sur le clavier et une vie sur le froncement de sourcils.
AndrewC

44

Les expressions régulières vous permettent d'écrire une machine à états finis (FSM) personnalisée de manière compacte, pour traiter une chaîne d'entrée. Il y a au moins deux raisons pour lesquelles l'utilisation d'expressions régulières est difficile:

  • Le développement de logiciels à l'ancienne implique beaucoup de planification, de modèles papier et de réflexion approfondie. Les expressions régulières s'intègrent très bien dans ce modèle, car pour écrire correctement une expression efficace, il faut beaucoup la regarder, visualiser les chemins du FSM.

    Les développeurs de logiciels modernes préfèrent de loin élaborer du code et utiliser un débogueur pour passer à travers l'exécution, pour voir si le code est correct. Les expressions régulières ne prennent pas très bien en charge ce style de travail. Une «exécution» d'une expression régulière est en fait une opération atomique. Il est difficile d'observer une exécution pas à pas dans un débogueur.

  • Il est trop facile d'écrire une expression régulière qui accepte accidentellement plus de données que vous n'en pensez. La valeur d'une expression régulière ne correspond pas vraiment à une entrée valide, elle ne correspond pas à une entrée non valide . Les techniques pour faire des "tests négatifs" pour les expressions régulières ne sont pas très avancées, ou du moins pas largement utilisées.

    Cela va jusqu'à rendre les expressions régulières difficiles à lire. En regardant simplement une expression régulière, il faut beaucoup de concentration pour visualiser toutes les entrées possibles qui devraient être rejetées, mais qui sont acceptées par erreur. Avez-vous déjà essayé de déboguer le code d'expression régulière de quelqu'un d' autre ?

S'il y a une résistance à l'utilisation d'expressions régulières chez les développeurs de logiciels aujourd'hui, je pense que c'est principalement dû à ces deux facteurs.


4
Il existe d'excellents outils pour déboguer les expressions rationnelles: regexbuddy.com
Jasper Bekkers

15
perl -Mre = debug -e "q [aabbcc] = ~ / ab * [cd] /"
Brad Gilbert

15
Je ne pense pas que je puisse jamais voir l'acronyme "FSM" sans penser au Flying Spaghetti Monster.
Shabbyrobe

4
@Shabbyrobe: Je ne veux pas offenser. Si vous le souhaitez, vous pouvez utiliser un automate fini déterministe (DFA).
Bill Karwin

37

Les gens ont tendance à penser que les expressions régulières sont difficiles; mais c'est parce qu'ils les utilisent mal. Écriture de lignes simples complexes sans aucun commentaire, indentation ou captures nommées. (Vous n'entamez pas votre expression SQL complexe sur une seule ligne, sans commentaires, indentation ou alias, n'est-ce pas?). Alors oui, pour beaucoup de gens, ça n'a pas de sens.

Cependant, si votre travail a quelque chose à voir avec l'analyse du texte (à peu près n'importe quelle application Web là-bas ...) et que vous ne connaissez pas l'expression régulière, vous craignez pour votre travail et vous perdez votre propre temps et celui de votre employeur. Il existe d' excellentes ressources pour tout vous apprendre à leur sujet, et bien plus encore.


2
Eh bien .. la différence est que plusieurs espaces ont une signification dans l'expression régulière, alors que dans d'autres langues, ils ne le font pas et c'est pourquoi ils sont généralement des doublures (qui se terminent parfois sur plusieurs lignes :)
Rado

14
@Rado: Perl, par exemple, a le xmodificateur pour les expressions rationnelles qui fait que les espaces blancs sont ignorés. Cela vous permet de mettre l'expression régulière sur quelques lignes et d'ajouter des commentaires.
Nathan Fellman le

9
De même, Python a re.Xaka re.VERBOSE.
Craig McQueen

2
De même, le xmodificateur en tcl. Je pense que c'est assez standard car tcl, contrairement à d'autres langages, n'utilise pas PCRE.
slebetman

2
@AndrewC C'est l'une des interprétations les plus grossières que cet article aurait pu avoir.
Jasper Bekkers

28

Parce qu'ils n'ont pas l'outil d'apprentissage le plus populaire dans les IDE communément acceptés: il n'y a pas d'assistant Regex. Pas même la saisie semi-automatique. Vous devez coder le tout par vous-même.


3
Ensuite, vous utilisez le mauvais IDE ... Même mon éditeur de texte fournit des indices regex.
CurtainDog

1
Par ailleurs, Expresso et The Regex Coach sont des outils très utiles pour construire des expressions régulières.
Mun

22
Comment diable voudriez-vous compléter automatiquement une expression régulière?
AmbroseChapel

3
EditPad Pro a une coloration syntaxique pour les expressions rationnelles dans la zone de recherche, mais je trouve cela plus ennuyeux qu'utile et je le garde désactivé. Mais je l'apprécie de me faire savoir quand j'ai des supports inégalés; les parenthèses en particulier peuvent être un ours à suivre.
Alan Moore

2
@AmbroseChapel - J'ai quelques années de retard dans cette discussion. Mais j'ai créé un mécanisme d' auto-complétion sur regexhero.net/tester. Il est initié par les constructions communes entre crochets ronds (), carrés []ou bouclés {}. Cela fonctionnera également hors de la barre oblique inverse.
Steve Wortham


16

Je ne pense pas qu'ils soient si controversés.

Je pense également que vous avez en quelque sorte répondu à votre propre question, car vous montrez à quel point il serait idiot de les utiliser partout ( tout n'est pas une langue régulière 2 ) ou d'éviter de les utiliser du tout. Vous, le programmeur, devez prendre une décision intelligente sur le moment où les expressions régulières aideront le code ou le blesseront. Face à une telle décision, deux choses importantes à garder à l'esprit sont la maintenabilité (qui implique la lisibilité) et l'extensibilité.

Pour ceux qui leur sont particulièrement opposés, je suppose qu'ils n'ont jamais appris à les utiliser correctement. Je pense que la plupart des gens qui passent seulement quelques heures avec un tutoriel décent les découvriront et deviendront couramment très rapidement. Voici ma suggestion par où commencer:

http://docs.python.org/howto/regex

Bien que cette page parle d'expressions régulières dans le contexte de Python, j'ai trouvé que les informations sont très applicables ailleurs. Il y a quelques éléments spécifiques à Python, mais je pense qu'ils sont clairement notés et faciles à retenir.


2
La page a semblé se déplacer vers docs.python.org/howto/regex
Dominic K

@DMan Merci. Je vais modifier ma réponse pour réfléchir.
allyourcode

11

Les expressions régulières sont aux chaînes ce que les opérateurs arithmétiques sont aux nombres, et je ne les considérerais pas comme controversés. Je pense que même un activiste OO assez militant comme moi (qui aurait tendance à choisir d'autres objets plutôt que des cordes) aurait du mal à les rejeter.


7

Le problème est que les regex sont potentiellement si puissantes que vous pouvez faire des choses avec elles pour lesquelles vous devriez utiliser quelque chose de différent.

Un bon programmeur doit savoir où les utiliser et où non. L'exemple typique est l'analyse des langues non régulières (voir Décider si une langue est régulière ).

Je pense que vous ne pouvez pas vous tromper si vous vous limitez d'abord à de vraies expressions régulières (pas d'extensions). Certaines extensions peuvent vous faciliter la vie, mais si vous trouvez quelque chose de difficile à exprimer comme une vraie expression régulière, cela peut bien être une indication qu'une expression régulière n'est pas le bon outil.


5

Vous pourriez presque aussi bien demander pourquoi les goto sont controversés.

Fondamentalement, lorsque vous obtenez autant de pouvoir "évident", les gens sont susceptibles d'en abuser pour des situations pour lesquelles ils ne sont pas la meilleure option. Le nombre de personnes demandant à analyser des fichiers CSV ou XML ou HTML dans des expressions rationnelles, par exemple, m'étonne. Ce n'est pas le bon outil pour le travail. Mais certains utilisateurs insistent sur l'utilisation des expressions rationnelles de toute façon.

Personnellement, j'essaie de trouver ce juste milieu - utilisez des expressions régulières pour ce qu'elles sont bonnes et évitez-les lorsqu'elles ne sont pas optimales.

Notez que les expressions régulières peuvent toujours être utilisées pour analyser les CSV, XML, HTML, etc. Mais généralement pas dans une seule expression régulière.


Bien sûr, vous pouvez analyser n'importe lequel de ces formats dans une seule expression régulière, c'est la puissance des expressions régulières, bébé! Que vous le vouliez ou non, c'est une tout autre affaire.
Jasper

4

Je ne pense pas que «controversé» soit le bon mot.

Mais j'ai vu des tonnes d'exemples où les gens disent "quelle est l'expression régulière dont j'ai besoin pour faire telle ou telle manipulation de chaîne?" qui sont des problèmes XY.

En d'autres termes, ils sont partis de l'hypothèse qu'un regex est ce dont ils ont besoin, mais ils seraient mieux avec un split (), une traduction comme tr /// de perl où les caractères sont substitués l'un à l'autre, ou juste un index ().


4

C'est un sujet intéressant.
De nombreux aficionados de regexp semblent confondre la concision de la formule avec l'efficacité.
En plus de cela, une expression rationnelle qui nécessite beaucoup de réflexion produit à son auteur une satisfaction massive qui la rend immédiatement légitime.

Mais ... les regexps sont si pratiques lorsque les performances ne sont pas un problème et que vous devez traiter rapidement une sortie de texte, en Perl par exemple. En outre, bien que les performances soient un problème, vous pouvez préférer ne pas essayer de battre la bibliothèque d'expressions régulières en utilisant un algorithme maison qui peut être bogué ou moins efficace.

En outre, il existe un certain nombre de raisons pour lesquelles les expressions rationnelles sont injustement critiquées, par exemple

  • l'expression rationnelle n'est pas efficace, car la construction de celle du haut n'est pas évidente
  • certains programmeurs "oublient" de ne compiler qu'une seule fois une expression rationnelle à utiliser plusieurs fois (comme un modèle statique en Java)
  • certains programmeurs optent pour la stratégie d' essai et d'erreur - fonctionne encore moins avec les regexps!

4

Ce que je pense, c'est apprendre les regex et maintenir les regex en impopulaire, la plupart des développeurs sont paresseux ou la plupart d'entre eux s'appuient sur des bibliothèques externes pour faire l'analyse pour eux ... ils comptent sur Google pour la réponse et demandent même dans les forums pour le code complet de leur problème. Mais quand vient l'implémentation ou la modification / maintenance d'une expression régulière, ils échouent tout simplement.

Il y a un dicton populaire "Les amis ne laissent pas les amis utiliser Regex pour analyser le HTML"

Mais en ce qui me concerne, j'ai fait des analyseurs HTML complets en utilisant Regex et je trouve que les regex sont meilleurs pour analyser les chaînes html en termes de vitesse et de mémoire (si vous avez une idée de ce que vous devez accomplir :))


2
Je pense qu'il est malhonnête d'écrire la plupart des développeurs ... comme paresseux. Je dirais que la syntaxe est très cryptique, peu intuitive et pleine de pièges, pour les non-initiés, ce qui conduit à une forte barrière à l'entrée. Pour la même raison, Perl a une "mauvaise" réputation pour beaucoup, mais c'est aussi un langage très puissant. C'est comme essayer de lire des expressions mathématiques avant de connaître les symboles. C'est intimidant, et les développeurs doivent être judicieux avec leur temps pour savoir qu'ils auront des avantages à apprendre cette syntaxe.
Katastic Voyage

Vous allez manquer des cas marginaux en HTML car HTML n'est pas un langage normal. Vous êtes en sécurité si votre intention est d'analyser un sous-ensemble connu de HTML
Boyang

2

Les expressions régulières sont un mystère sérieux pour beaucoup de gens, y compris moi-même. Cela fonctionne très bien, mais c'est comme regarder une équation mathématique. Je suis heureux de signaler cependant que quelqu'un a finalement créé un emplacement consolidé de diverses fonctions d'expression régulière sur http://regexlib.com/ . Maintenant, si Microsoft ne créait qu'une classe d'expression régulière qui ferait automatiquement une grande partie des choses courantes comme l'élimination des lettres ou le filtrage des dates.


2
Vous manquez le point. L'idée des regexes est que vous investissez un peu de temps dans leur apprentissage et lorsque vous avez terminé, vous n'avez plus besoin d'un cours magique de «lecture de date». Au lieu de cela, cela ne demande que très peu d'efforts. De plus, il faudra aussi peu d'efforts pour en écrire un pour "aaaa / mm / jj" que pour en écrire un pour "mm-jj-aaaa", ou même un pour "mm-aaaa / jj" (qui a gagné n'arrive pas souvent, mais c'est un exemple de la façon dont vous pouvez faire des choses qu'une classe magique ne pourra jamais faire ").
Jasper

1

Je trouve parfois les expressions régulières inestimables. Quand j'ai besoin de faire des recherches "floues", et peut-être de les remplacer. Quand les données peuvent varier et avoir un certain caractère aléatoire. Cependant, lorsque je dois effectuer une recherche simple et remplacer, ou rechercher une chaîne, je n'utilise pas d'expressions régulières. Bien que je connaisse beaucoup de gens qui le font, ils l'utilisent pour tout. Telle est la controverse.

Si vous voulez mettre un clou dans le mur, n'utilisez pas de marteau. Oui, cela fonctionnera, mais au moment où vous obtenez le marteau, je pourrais mettre 20 punaises dans le mur.

Les expressions régulières doivent être utilisées pour ce pour quoi elles ont été conçues, et rien de moins.


0

Bien que je pense que les regex sont un outil essentiel, la chose la plus ennuyeuse à leur sujet est qu'il existe différentes implémentations. De légères différences de syntaxe, de modificateurs et, surtout, de «cupidité» peuvent rendre les choses vraiment chaotiques, nécessitant des essais et des erreurs et parfois des bugs déroutants.


en quoi les implémentations d'expression régulière diffèrent-elles dans leur approche de l'appariement maximal, ce que vous appelez, je pense, la «cupidité»? Voulez - vous dire la différence entre le plus à gauche plus longue par rapport à la plus longue extrême gauche sémantique? C'est la seule différence que je connaisse; c'est-à-dire si la cupidité l'emporte sur l'empressement ou vice versa .
tchrist

0

Dans certains cas, je pense que vous DEVEZ les utiliser. Par exemple pour construire un lexer.

À mon avis, c'est le point de vue des personnes qui peuvent écrire des expressions rationnelles et des personnes qui ne le font pas (ou à peine). Personnellement je pense que c'est une bonne idée par exemple de valider la saisie d'un formulaire, que ce soit en javascript pour avertir l'utilisateur, ou en langage côté serveur.


0

Je pense que c'est une technique moins connue des programmeurs. Donc, il n'est pas largement accepté. Et si vous avez un responsable non technique pour revoir votre code ou revoir votre travail, alors une expression régulière est très mauvaise. Vous passerez des heures à écrire une expression régulière parfaite, et vous obtiendrez peu de notes pour le module en pensant qu'il / elle a écrit si peu de lignes de code. De plus, comme dit ailleurs, la lecture des expressions régulières est une tâche très difficile.


1
La lecture d'expressions régulières n'est une tâche difficile que lorsque le programmeur qui les a conçues n'a pas réussi à utiliser les espaces blancs, les commentaires, les identificateurs alphanumériques et peut-être aussi les sous-programmes intégrés via une exécution retardée. En bref, toutes les techniques de génie logiciel applicables à la programmation générale devraient également être suivies dans les expressions régulières. Si ces principes sont ignorés, alors l'auteur ne produit pas de code professionnel.
tchrist

Je pense que votre manager ne sait pas que "Le vrai héros de la programmation est celui qui écrit du code négatif."
Rajeev

Si votre manager va vous taper pour avoir accompli le travail avec 3 lignes de code (y compris les expressions régulières), tout en faisant l'éloge d'un collègue doofus qui l'a fait dans 900 lignes d'assembleur ... je suggère de trouver un nouveau travail.
Phil Perry

0

Les systèmes d'expression régulière décents tels que ceux utilisés dans lex et yacc pour la définition du compilateur sont bons, très utiles et propres. Dans ces systèmes, les types d'expression sont définis en fonction des autres. Ce sont les hideuses expressions régulières à une ligne géantes à bruit de ligne malformées et hideuses qui se trouvent couramment dans les codes perl et sed (etc.) qui sont `` controversées '' (ordures).


-4

La meilleure utilisation valide et normale de l'expression régulière est pour la validation du format d'adresse e-mail.

C'est une bonne application.

J'ai utilisé d'innombrables expressions régulières comme ponctuelles dans TextPad pour masser des fichiers plats, créer des fichiers csv, créer des instructions d'insertion SQL et ce genre de choses.

Les expressions régulières bien écrites ne devraient pas être trop lentes. Habituellement, les alternatives, comme des tonnes d'appels à remplacer, sont des options beaucoup plus lentes. Autant le faire en un seul passage.

De nombreuses situations nécessitent des expressions exactement régulières et rien d'autre.

Le remplacement de caractères spéciaux non imprimables par des caractères inoffensifs est un autre bon usage.

Je peux bien sûr imaginer qu'il existe des bases de code qui surexploitent les expressions régulières au détriment de la maintenabilité. Je ne l'ai jamais vu moi-même. J'ai été en fait évité par les réviseurs de code pour ne pas utiliser suffisamment d'expressions régulières.


10
L'expérience montre que les regex sont en fait un outil assez médiocre pour la validation du format d'adresse e-mail. Un validateur de format vraiment complet implémenté comme expression régulière est une monstruosité de plusieurs centaines de caractères, tandis que la plupart des validateurs "assez bons" plus courts que la plupart des gens mettent 5 minutes à créer rejetteront de grandes catégories d'adresses valides et livrables.
Dave Sherohman

Je t'entends mec. Je parlais du «assez bon» et, même si les grandes étendues peuvent être grandes en théorie, considérez le pourcentage de couverture que vous obtenez dans une expression aussi courte. Moi aussi, j'ai vu la monstruosité, mais quelle est votre alternative élégante?
Chris Morley

2
J'ai utilisé quelque chose comme \ w @ \ w +. \ W + pour trouver rapidement une adresse e-mail dans un énorme répertoire de fichiers où la vitesse était importante et où quelques faux positifs ou faux négatifs n'étaient pas importants. Mais la meilleure façon de valider une adresse e-mail semble être de lui envoyer un e-mail.
RossFabricant

Ouais, l'adresse électronique est un désordre désordonné stackoverflow.com/questions/611775/…
Nick Van Brunt

@Nick, @Dave: La validation de l'adresse e-mail ne doit pas être un désordre désagréable.
tchrist
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.