42 votes

Comment écrire plus d'expressions régulières maintenables?

J'ai commencé à sentir que l'utilisation des expressions régulières diminue la maintenabilité du code. Il ya quelque chose de mal à propos de la concision et de la puissance des expressions régulières. Perl composés cela avec des effets secondaires comme des opérateurs par défaut.

J'ai l'habitude de documenter les expressions régulières avec au moins une phrase donnant l'intention de base et au moins un exemple de ce qui pourrait correspondre.

Parce que les expressions régulières sont construit je crois qu'il est d'une nécessité absolue de commentaire sur les composantes les plus importantes de chaque élément de l'expression. Malgré cela, même mes propres expressions régulières me en me grattant la tête comme si je lis un Klingon.

Avez-vous intentionnellement abrutir vos expressions régulières? Ne vous décomposer éventuellement plus courte et plus puissantes dans le plus simple des étapes? J'ai renoncé à la nidification des expressions régulières. Sont il de l'expression régulière à des constructions de vous éviter en raison de mainainability questions?

Ne laissez pas cet exemple de nuage de la question.

Si la suite par Michael Ash eu une sorte de bug auriez-vous des perspectives de rien faire, mais de le jeter entièrement?

^(?:(?:(?:0?[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0?[13-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:0?2(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$

Par demande la fin exacte peut être trouvé à l'aide de M. Ash lien ci-dessus.

Matchs 01.1.02 | 11-30-2001 | 2/29/2000

Non-Matchs 02/29/01 | 13/01/2002 | 11/00/02

33voto

Mitch Wheat Points 169614

L'utilisation d'Expresso qui donne à une organisation hiérarchique, l'anglais rupture d'une regex.

Ou

Cette astuce de Darren Neimke:

.NET permet d'expression régulière les modèles créés avec embedded commentaires sur l' RegExOptions.IgnorePatternWhitespace option du compilateur et de l' (?#...) la syntaxe intégré au sein de chaque ligne de la chaîne de modèle.

Cela permet de pseudo-code comme commentaires pour être incorporé dans chaque ligne et a la suite d'incidence sur la lisibilité:

Dim re As New Regex ( _
    "(?<=       (?# Start a positive lookBEHIND assertion ) " & _
    "(#|@)      (?# Find a # or a @ symbol ) " & _
    ")          (?# End the lookBEHIND assertion ) " & _
    "(?=        (?# Start a positive lookAHEAD assertion ) " & _
    "   \w+     (?# Find at least one word character ) " & _
    ")          (?# End the lookAHEAD assertion ) " & _
    "\w+\b      (?# Match multiple word characters leading up to a word boundary)", _
    RegexOptions.Multiline Or RegexOptions.IgnoreCase Or RegexOptions.IgnoreWhitespace _
)

Voici un autre .NET exemple (exige l' RegexOptions.Multiline et RegexOptions.IgnorePatternWhitespace options):

static string validEmail = @"\b    # Find a word boundary
                (?<Username>       # Begin group: Username
                [a-zA-Z0-9._%+-]+  #   Characters allowed in username, 1 or more
                )                  # End group: Username
                @                  # The e-mail '@' character
                (?<Domainname>     # Begin group: Domain name
                [a-zA-Z0-9.-]+     #   Domain name(s), we include a dot so that
                                   #   mail.somewhere is also possible
                .[a-zA-Z]{2,4}     #   The top level domain can only be 4 characters
                                   #   So .info works, .telephone doesn't.
                )                  # End group: Domain name
                \b                 # Ending on a word boundary
                ";

Si votre RegEx est applicable à un problème commun, une autre option est de documenter et de se soumettre à RegExLib, où il sera évalué et commenté. Rien ne vaut de nombreuses paires d'yeux...

Une autre expression régulière de l'outil est L'organisme de réglementation

19voto

James Points 7234

D'habitude, j'essaye simplement de placer tous mes appels d'expression régulière dans leur propre fonction, avec un nom significatif et des commentaires de base. J'aime considérer les expressions rationnelles comme un langage écrit uniquement, lisible uniquement par celui qui l'a écrit (à moins que ce ne soit vraiment simple). Je m'attends vraiment à ce que quelqu'un ait probablement besoin de réécrire complètement l'expression s'il devait changer son intention et il est probablement préférable d'améliorer la formation de l'expression régulière.

17voto

chaos Points 69029

Le but du modificateur PCRE / x dans la vie est de vous permettre d’écrire des expressions rationnelles plus facilement, comme dans cet exemple trivial:

 my $expr = qr/
    [a-z]    # match a lower-case letter
    \d{3,5}  # followed by 3-5 digits
/x;
 

8voto

paxdiablo Points 341644

Certaines personnes utilisent REs pour le mal de choses (je suis en attente pour le premier DONC, la question sur la façon de détecter valide d'un programme en C++ à l'aide d'un seul RE).

J'ai l'habitude de trouver que, si je ne rentre pas mon RE dans un délai de 60 personnages, c'est mieux d'être un morceau de code qui seront presque toujours être plus lisible.

En tout cas, j'ai toujours le document, dans le code, ce que le RE est censé atteindre, dans les moindres détails. C'est parce que je sais, par une amère expérience, combien il est difficile pour quelqu'un d'autre (ou même moi, six mois plus tard) de venir et d'essayer de comprendre.

Je ne crois pas qu'ils sont mauvais, bien que je ne crois que certaines personnes qui les utilisent sont mauvais (ne cherche pas à vous, Michael Ash :-). Ils sont un excellent outil, mais, comme une tronçonneuse, vous allez couper vos jambes si vous ne savez pas comment les utiliser correctement.

Mise à JOUR: en Fait, j'ai juste suivi le lien de monstruosité, et c'est pour valider m/d/y de format de dates entre les années 1600 et 9999. C'est un classique cas d'où part entière du code sera plus lisible et maintenable.

Vous venez de découper en trois champs et de contrôler les valeurs individuelles. Je l'avais presque le considérer comme une infraction digne de résiliation si l'un de mes serviteurs acheté ce pour moi. Je serais certainement de les envoyer de nouveau à l'écrire correctement.

4voto

fuzzy-waffle Points 585

J'ai trouvé une méthode intéressante consiste simplement à diviser le processus d'appariement en plusieurs phases. Il ne s’exécute probablement pas aussi vite, mais vous avez également l’avantage de pouvoir dire à un niveau de grain plus fin pourquoi la correspondance n’a pas lieu.

Une autre voie consiste à utiliser l'analyse syntaxique LL ou LR. Certaines langues ne sont pas exprimables sous forme d'expressions régulières probablement même avec les extensions non-fsm de perl.

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