Pourquoi les expressions régulières ne peuvent-elles pas utiliser des mots-clés au lieu de caractères?

StackOverflow https://stackoverflow.com/questions/629573

  •  08-07-2019
  •  | 
  •  

Question

D'accord, je comprends à peine les bases de RegEx, mais pourquoi ne pourraient-ils pas le concevoir pour qu'il utilise des mots-clés (comme SQL) au lieu de caractères et de symboles génériques génériques?

S'agit-il de performances puisque le RegEx est interprété / analysé au moment de l'exécution? (non compilé)

Ou peut-être pour la rapidité de l'écriture? Considérant que lorsque vous apprenez quelques & Quot; simples & Quot; combinaisons de caractères, il devient plus facile de taper 1 caractère au lieu d'un mot clé?

Était-ce utile?

La solution

Vous voulez vraiment this ?

Pattern findGamesPattern = Pattern.With.Literal(@"<div")
    .WhiteSpace.Repeat.ZeroOrMore
    .Literal(@"class=""game""").WhiteSpace.Repeat.ZeroOrMore.Literal(@"id=""")
    .NamedGroup("gameId", Pattern.With.Digit.Repeat.OneOrMore)
    .Literal(@"-game""")
    .NamedGroup("content", Pattern.With.Anything.Repeat.Lazy.ZeroOrMore)
    .Literal(@"<!--gameStatus")
    .WhiteSpace.Repeat.ZeroOrMore.Literal("=").WhiteSpace.Repeat.ZeroOrMore
    .NamedGroup("gameState", Pattern.With.Digit.Repeat.OneOrMore)
    .Literal("-->");

D'accord, mais c'est vos funérailles , mec.

Téléchargez la bibliothèque qui fait cela ici:
http://flimflan.com/blog/ReadableRegularExpressions.aspx

Autres conseils

Les expressions régulières ont un arrière-plan mathématique (en fait, la théorie des langues) et sont codées un peu comme une formule mathématique . Vous pouvez les définir à l'aide d'un ensemble de règles, par exemple

  • chaque caractère est une expression régulière se représentant
  • si a et b sont des expressions régulières, alors a?, a|b et ab sont également des expressions régulières
  • ...

L'utilisation d'un langage basé sur les mots clés constituerait un lourd fardeau pour les expressions rationnelles simples. La plupart du temps, vous utiliserez simplement une simple chaîne de texte comme motif de recherche:

grep -R 'main' *.c

Ou peut-être des modèles très simples:

grep -c ':-[)(]' seidl.txt

Une fois que vous vous êtes habitué aux expressions régulières, cette syntaxe est très claire et précise. Dans des situations plus complexes, vous utiliserez probablement autre chose, car une expression régulière de grande taille est évidemment difficile à lire.

Perl 6 fait un pas de géant en termes de lisibilité de regex. Considérons une adresse du formulaire: 100 E Main St Springfield MA 01234

Voici une expression rationnelle compatible Perl 5 moyennement lisible à analyser (nombreux cas de coins non traités):

 m/
     ([1-9]\d*)\s+
     ((?:N|S|E|W)\s+)?
     (\w+(?:\s+\w+)*)\s+
     (ave|ln|st|rd)\s+
     ([:alpha:]+(?:\s+[:alpha:]+)*)\s+
     ([A-Z]{2})\s+
     (\d{5}(?:-\d{4})?)
  /ix;

Cette regex Perl 6 a le même comportement:

grammar USMailAddress {
     rule  TOP { <addr> <city> <state> <zip> }

     rule  addr { <[1..9]>\d* <direction>?
                  <streetname> <streettype> }
     token direction { N | S | E | W }
     token streetname { \w+ [ \s+ \w+ ]* }
     token streettype {:i ave | ln | rd | st }
     token city { <alpha> [ \s+ <alpha> ]* }
     token state { <[A..Z]>**{2} }
     token zip { \d**{5} [ - \d**{4} ]? }
  }

Une grammaire Perl 6 est une classe et les jetons sont des méthodes invocables. Utilisez-le comme ceci:

if $addr ~~ m/^<USMailAddress::TOP>$/ {
     say "$<city>, $<state>";
}

Cet exemple provient d'un exposé que j'ai présenté au atelier Frozen Perl 2009 . L’implémentation de Perl 6 par Rakudo est suffisamment complète pour que cet exemple fonctionne aujourd’hui.

Eh bien, si vous aviez des mots-clés, comment les différencieriez-vous facilement du texte qui correspond réellement? Comment géreriez-vous les espaces?

Texte source Société: A Dept .: B

regex standard:

Company:\s+(.+)\s+Dept.:\s+(.+)

Ou même:

Company: (.+) Dept. (.+)

Mot-clé regex (essayer très fort de ne pas avoir un homme de paille ...)

"Company:" whitespace.oneplus group(any.oneplus) whitespace.oneplus "Dept.:" whitespace.oneplus group(any.oneplus)

Ou simplifié:

"Company:" space group(any.oneplus) space "Dept.:" space group(any.oneplus)

Non, ce n'est probablement pas mieux.

Parce que cela correspond à la théorie des langues formelle et à sa notation mathématique.

C'est la faute de Perl ...!

En fait, plus précisément, les expressions rationnelles proviennent des premiers développements Unix, et la syntaxe concise était alors beaucoup plus prisée. Le stockage, le temps de traitement, les terminaux physiques, etc. étaient très limités, assez différents de ceux d’aujourd’hui.

L'historique des expressions régulières sur Wikipedia en explique plus.

Il existe des alternatives à Regex, mais je ne suis pas sûr qu’elles aient vraiment attiré l’attention.

EDIT: corrigé par John Saunders: les expressions rationnelles ont été popularisées par Unix, mais ont d'abord été implémentées par le QED éditeur. Les mêmes contraintes de conception s'appliquaient, encore plus, aux systèmes antérieurs.

En fait, non, le monde n’a pas commencé avec Unix. Si vous lisez l'article de Wikipedia, vous verrez que

  

Dans les années 1950, le mathématicien Stephen Cole Kleene a décrit ces modèles en utilisant sa notation mathématique appelée ensembles ordinaires. Le langage SNOBOL était une implémentation précoce du filtrage par motif, mais pas identique aux expressions régulières. Ken Thompson a construit la notation de Kleene dans l'éditeur QED afin de faire correspondre les modèles dans les fichiers texte. Il a par la suite ajouté cette fonctionnalité à l'éditeur Unix, ce qui a finalement conduit à l'utilisation des expressions régulières par l'outil de recherche populaire grep

Ceci est beaucoup plus tôt que PERL. L'entrée Wikipedia sur les expressions régulières attribue les premières implémentations d'expressions régulières à Ken Thompson d'UNIX gloire, qui les a implémentées dans le CQF, puis dans l’éditeur ed . J'imagine que les commandes portaient des noms abrégés pour des raisons de performances, mais beaucoup avant d'être côté client. Maîtriser les expressions régulières est un excellent livre sur les expressions régulières, qui offre la possibilité d'annoter une expression régulière (avec le drapeau) pour le rendre plus facile à lire et à comprendre.

Parce que les expressions régulières, comme beaucoup d'autres choses provenant d'UNIX, sont laconiques, privilégiant la brièveté à la lisibilité. C'est en fait une bonne chose. J'ai fini par écrire des expressions régulières (contre mon meilleur jugement) de 15 lignes. Si cela avait une syntaxe verbeuse, ce ne serait pas une regex, ce serait un programme.

Il est en fait assez facile de mettre en oeuvre un " wordier " forme de regex - veuillez consulter ma réponse ici . En un mot: écrivez une poignée de fonctions qui renvoient des chaînes de regex (et prenez des paramètres si nécessaire).

Je ne pense pas que les mots clés apporteraient un avantage. Les expressions régulières en tant que telles sont complexes mais également très puissantes.

Ce qui me semble plus déroutant, c’est que chaque bibliothèque de support invente sa propre syntaxe au lieu d’utiliser (ou d’étendre) la regex Perl classique (par exemple, \ 1, $ 1, {1}, ... pour les remplacements et de nombreux autres exemples). .

Je connais mal sa réponse à votre question, mais RegExBuddy est doté d'une fonctionnalité qui explique votre expression régulière. en anglais simple. Cela pourrait le rendre un peu plus facile à apprendre.

Si la langue que vous utilisez prend en charge les expressions rationnelles Posix , vous pouvez les utiliser.

Un exemple:

\d

serait identique à

[:digit:]

La notation entre crochets est beaucoup plus claire sur ce à quoi elle correspond. J'apprendrais toujours les & "; Symboles et symboles génériques génériques, car vous les verrez toujours dans le code des autres et vous devez les comprendre.

Il existe d'autres exemples dans le dans la page de regular-expressions.info .

Pour une raison quelconque, ma réponse précédente a été supprimée. Quoi qu'il en soit, je pense que la machine Ruby Regexp conviendrait parfaitement, à l'adresse http://www.rubyregexp.sf.net C’est mon propre projet, mais je pense que cela devrait fonctionner.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top