web-dev-qa-db-fra.com

Une meilleure façon de faire regex?

Je n'aime vraiment pas les expressions régulières, chaque fois que je reviens, je semble avoir à la désapprouver. Il est également incroyablement difficile de maintenir, de modifier et d'un coup d'œil comprendre ce qu'il fait.

Quelqu'un a-t-il déjà essayé d'écrire une autre couche sur le dessus qui transforme des déclarations "SQL similaires" sémantiques dans Regex? J'imagine que ça marche dans le sens de:

AnotherString = "coffee hello beep 15"

FindString.StartsWith string longer than 5
FindString.Contains "beep" after "hello"
FindString.EndsWidth int < 20
FindString.DoesntContain "no!!" and DoesntContain "what!"
Foreach FindString match in AnotherString
    ...
Next

Ce n'est probablement pas le plus grand exemple de jamais, mais l'idée est que le motif est construit avec une sorte de langage significatif sémantique pouvant se décomposer dans des expressions classiques traditionnelles. Ce qui précède serait beaucoup plus facile pour un développeur à modifier. Je suis une sorte d'invision qui est comme SQL/Linq dans une certaine mesure.

Cela rendrait beaucoup plus sémantique et maintenante. Cela a-t-il été essayé avant et s'agit-il d'une mauvaise idée/bonne idée d'essayer cela? Ça pourrait marcher?

éditer

C'est peut-être un meilleur exemple (je sais que les URL sont notoirement difficiles à analyser et cela est trop simplifié):

string UserInputtedURL = "http://www.google.com/page.html?ID=5"

Protocols = {"http", "https"};
Domains = {"com", "net", "org"}
Rule.CaseSensitive = false;
Rule starts with Protocols OR starts with "www";
Rule followedby string endson "."
Rule followedby Domains
Rule if stringend or endswidth " " end else continuewith Ruleset2

RuleSet2.startswith "/"
etc...

if(UserInputtedURL.Matches(Rule)){
    // URL is valid!
}
8
Tom

Cela a déjà été fait, du moins pour Perl.

Voir http://search.cpan.org/~chromatic/regexp-english-1.01/lib/regexp/english.pm

Il n'a pas vraiment pris le monde par la tempête, mais cela pourrait être un bon point de départ si vous voulez écrire un mécanisme similaire pour une autre langue.

Ce n'est pas si difficile d'obtenir les bases des regexnes. Je trouve des dialectes de commutation (EMACS VS Perl compatible Expressions régulières contre cette variante étrange dans la boîte de dialogue Visual Studio Trouvez, par exemple) le problème le plus important. Je ne serais pas motivé pour apprendre une version "plaine anglaise". Il est presque plus facile d'accepter l'abstraction, car la traduction en langage naturel des symboles couramment utilisés est également imparfaite.

8
JasonTrue

Ce que vous proposez est incroyablement Verbose. Même si la regex peut être difficile à digérer si elle est mal faite et en prend certains (seulement un peu, je réclamerais - je lisais rarement des regextes, mais je me souviens encore de la syntaxe pour les caractéristiques les plus importantes (répétition, classes de caractères, lunettes de vue ) Et peut lire des expressions à l'aide de ces fonctionnalités relativement couramment facilement), je préférerais que ce soit quelque chose comme ceci, ce qui me permet de saisir une phrase pseudo-anglaise complète pour quelque chose qui peut être parfaitement exprimé avec quelques personnages. Considérons également la complexité (et la préjuzaine d'erreur) d'une implémentation d'une telle langue!

Un autre problème que je dois élever: Les chèques que vous utilisez comme des exemples incluent certaines choses qui sont totalement déraisonnables à faire avec Regex - se terminant par un entier est suffisamment facile, mais les numéros de comparaison sont un non-go avec regex . En outre, bon nombre de ces tests sont écrits plus facilement avec les outils de traitement de la chaîne Nativ de la langue de programmation - Vérification de la longueur, par exemple ou la vérification de la sous-chaîne si la chaîne devient plus longue ou dynamique. Le fait que les expexitions existent et sont utiles ne signifie parfois pas que vous devez les utiliser pour tout traitement de chaîne. Utilisez-les avec soin et tout va bien.

6
user7043

Ce qui est simple aux humains est sans fin complexe aux ordinateurs:

Ce que vous décrivez dans presque AppleScript comme dans sa syntaxe et que AppleScript est universellement détesté, même par des personnes qui le savent bien, la syntaxe peut sembler facile et lisible, mais sa verbosité est sa baisse, à moins que vous ne le faisiez jamais jour, vous oubliez Toutes les règles de la grammaire et des mots clés et cela deviennent aussi opaques que la syntaxe de Regex. Il est difficile pour les débutants de comprendre à cause de la verbosité et durs pour les experts en raison de sa verbosité.

Votre exemple de paille artificielle Exemple:

Rule followedby string endson "."

Alors, comment puis-je me rappeler d'utiliser followedby au lieu de followed by ou after ou before ou precedes ou preceding ou une autre des alternatives de dizaines d'anglais à ce concept de "venir après" autre chose . Vous pouvez appliquer la même logique à endson qui pourrait être endswith ou endingwith ou ending, vous devrez toujours avoir une feuille de triche ou un livre à utiliser votre syntaxe proposée.

5
user7519

Bien sûr, cela pourrait fonctionner, mais ce serait extrêmement difficile à mettre en œuvre (IMHO), lorsque vous prenez en compte tout, sauf les expressions les plus élémentaires.

Regex est une langue de tous. Une fois que vous avez compris comment cela fonctionne, vous n'oubliez pas (vous aurez peut-être besoin d'un rafraîchissement sur la syntaxe, mais c'est la même chose pour toutes les langues) et une enveloppe devient inutile (et les frais généraux supplémentaires seraient indésirables).

Je pensais (quelque peu) comme vous jusqu'à ce que je lisais Maîtriser des expressions régulières (O'Reilly). Je recommandais vivement de le ramasser.

3
Demian Brecht

La meilleure façon de faire des expressions régulières est de les apprendre et de les comprendre, ou de ne pas les utiliser du tout. En utilisant un autre outil comme une excuse pour ne pas apprendre les expressions régulières signifie que vous devez les "apprendre" à chaque fois que vous les rencontrez.

Passez une journée, juste une journée (complète, non distribuée) pour étudier profondément les expressions régulières et vous serez récompensé par un nouvel outil que vous pouvez utiliser toute votre carrière. Vous aurez également une compréhension beaucoup plus grande quand elles sont appropriées et - plus important encore - quand ils ne le sont pas.

1
Bryan Oakley

Une alternative aux expressions régulières est forme de backus-naur et d'autres variations humaines comme EBNF ou ABNF. À peu près, chaque partie de la grammaire est cassée dans une "règle de production", avec une définition non mortelle à gauche et une séquence de terminaux et de non-mines décrivant la règle à droite. Votre exemple, dans BNF ressemblerait à quelque chose comme ceci:

expr ::= startword "hello" "beep" endword
       ;

startword ::= Word_CHAR Word_CHAR Word_CHAR Word_CHAR Word_CHAR 
            | startword Word_CHAR
            ;

endword ::= DIGIT
          | "1" DIGIT
          ;

De plus, BNF arrive à express Langues libres , une superset appropriée des langues ordinaires décrivent les expressions ordinaires.