2010-05-02 5 views
0

Vous recherchez simplement une faveur pour écrire une expression régulière correspondant à l'ensemble de chaînes suivant. Je veux écrire une expression qui correspond à toutes les chaînes suivantes TCLBesoin d'aide pour écrire une expression rationnelle - TCL

i) (XYZ XZZ XVZ XWZ)

Clue: chaîne de départ est fin de chaîne X et Z est le même pour toutes les paires. Seule la chaîne moyenne est différente YZV W.

Mon essai: [regexp {^X([Y|Z|V|W]*)Z$}]

Je veux écrire un autre regexp qui attrape/correspond uniquement à la chaîne suivante où vient

ii) (XYZ)

Mon essai: [regexp {^X([Y]*)Z$}] ou simplement regexp {^XYZ$}

Je veux juste m'assurer que c'est une approche correcte. Est-il un autre moyen disponible pour optimiser l'expression rationnelle :)

i) 1ère question Testé

set to_Match_Str "XYZ XZZ XVZ XWZ" 
    foreach {wholeStr to_Match_Str} [regexp -all -inline {X[YZVW]Z} $to_Match_Str] { 

    puts "MATCH $to_Match_Str in the list" 
    } 

Il imprime uniquement XZZ XWZ de la liste. Son omission XYZ & XVZ Lorsque j'inclue la parenthèse [regexp -all -inline {X ([YZVW]) Z} $ to_Match_Str]. Il imprime tous les caractères du milieu correctement YZVW

Répondre

0

Mon procès: [regexp {^ X ([Y | Z | V | W] *) Z $}]

Cela correspondrait à la chaîne est , mais comme vous utilisez le multiplicateur *, il correspondrait également aux chaînes telles que "XZ", "XYYYYYYYYYYYYYYYYZ" et "XYZYVWZWWWZVYYWZ". Pour correspondre au caractère du milieu une seule fois, ne pas utiliser un multiplicateur:

^X([Y|Z|V|W])Z$ 

Mon procès: [regexp {^ X ([Y] *) Z $}]

Le même là, il va également correspondre à des chaînes comme "XZ", "XYYZ" et "XYYYYYYYYYYYYYYYYZ". Ne pas mettre un multiplicateur après l'ensemble:

^X([Y])Z$ 

ou tout simplement regexp {^} XYZ $

qui n'attraper quoi que ce soit. Pour faire faire la même chose que l'autre (attraper le caractère Y), vous avez besoin des parenthèses:

^X(Y)Z$ 
3

i) (XYZ XZZ XVZ XWZ)

Clue: chaîne de démarrage est X et Z fin de chaîne est même pour toutes les paires. Seule la chaîne du milieu est différente Y Z V W.

Mon essai: [regexp {^X([Y|Z|V|W]*)Z$}]

En supposant que vous n'êtes pas après parenthèses littérales dans le lot entier, vous correspondez qu'utiliser ceci:

regexp {X([YZVW])Z} $string -> matchedSubstr 

C'est parce que les chaînes intérieures sont tous les caractères simples. (Il stocke également la sous-chaîne correspondante dans la variable matchedSubstr, choisissez n'importe quel nom de variable que vous voulez.) Vous ne devriez pas utiliser | à l'intérieur d'un [] dans une expression régulière, car il n'a pas de signification particulière là. (Vous devrez peut-être ajouter ^$ points d'ancrage autour de l'extérieur.)

D'autre part, si vous voulez faire correspondre plusieurs séquences de caractères (dont le Y etc. sont tout simplement stand-ins pour) vous utilisez ceci:

regexp {X(Y|Z|V|W)Z} $string -> matchedSubstr 

Notez que |est être utilisé ici, mais [] est pas.

Si votre chaîne réelle a plusieurs de ces chaînes (selon le modèle que vous utilisez pour les faire correspondre), la meilleure façon de les extraire tout est avec les -all -inline options à regexp, généralement utilisés dans un foreach comme celui-ci:

foreach {wholeStr matchedSubstr} [regexp -all -inline {X([YZVW])Z} $string] { 
    puts "Hey! I found a $matchSubstr in there!" 
} 

Mélanger et assortir au goût.

Mon essai: [regexp {^X([Y]*)Z$}] ou simplement regexp {^XYZ$}

voulez juste vous assurer que son approche correcte. Existe-t-il un autre moyen d'optimiser l'expression rationnelle :)

Ceci est optimal pour une comparaison exacte. Et en fait, Tcl optimisera cela en interne pour un test d'égalité de chaîne droite si c'est littéral.

+1

bien, il ne fait pas plus autorité qu'une réponse d'un membre de l'équipe de base Tcl. À votre santé. :) –

+0

Le seul petit problème avec cette question était de savoir exactement ce qui a été demandé. (Comme d'habitude, ceux qui sont habiles à poser des questions n'ont généralement pas besoin de demander en premier lieu donc je préfère essayer d'aider les gens à poser de meilleures questions :-)) –

+0

@Donal 1ère Question Testée set to_Match_Str " XYZ XZZ XVZ XWZ » {foreach wholeStr to_Match_Str} [regexp -Tous inline {X [YZVW] Z} to_Match_Str $] { met "MATCH $ to_Match_Str dans la liste" } Il imprime uniquement XZZ XWZ de la liste . Il laisse XYZ & XVZ Quand j'inclus la parenthèse [regexp -all -inline {X ([YZVW]) Z} $ to_Match_Str]. Il imprime correctement tous les caractères du milieu Y Z V W – user330727

0

Vous pouvez utiliser l'outil Visual Regexp pour vous aider, il fournit des commentaires lorsque vous construisez votre expression régulière.

Questions connexes