2010-08-16 6 views
1

Ok je suis arrivé cet exemple d'expression régulière livre de recettesLookahead confusion

^(?=.{3}$).* 

Le regex ci-dessus est utilisé pour limiter la longueur d'un motif arbitraire

Si je teste à nouveau « aaabbb », échouer complètement

d'après ce que je comprends rechercher tout caractère qui précède par un caractère 3 length.SO il doit correspondre à « bbb », mais ce ne est pas

une autre question, shou ld lookbehind suit ce modèle x (? = x)

+0

Ce que vous utilisez est une affirmation d'anticipation comme il regarde les personnages qui ne sont pas encore consommés . Une assertion de look-behind regarderait les caractères qui sont déjà consommés. – Gumbo

+0

Mais qu'essayez-vous exactement d'accomplir? – Gumbo

+0

edited: limite la longueur d'un motif arbitraire – slier

Répondre

5

C'est en fait une assertion lookahead et non une assertion lookbehind. Le^ancre la correspondance au début de la chaîne, il affirme ensuite que le début de la chaîne doit être suivi de 3 caractères suivis de la fin de la chaîne.

Modifier: J'aurais probablement dû mentionner que le. * À la fin est ensuite utilisé pour faire correspondre ces trois caractères, car une assertion anticipée ne consomme aucun caractère.

+0

ce que vous voulez dire par ne pas consommer de caractères? – slier

+0

Je veux dire qu'après avoir terminé l'assertion de lookahead, le moteur Regex continue de comparer la chaîne à partir du moment où elle est entrée dans le lookahead. Donc, étant donné le modèle '^ (? = Foo) (.*) $ 'et l'entrée' foobar' la capture de valeur par le groupe de capture 1 serait 'foobar'. Le motif va d'abord effectuer l'anticipation, c'est-à-dire vérifier si le début de la chaîne est foo, il passera alors sur le '. *' Puisque le lookahead ne consomme aucun caractère, ce qui signifie que la première lettre correspond à. le f puis le o et ainsi de suite jusqu'à ce qu'il ait capturé 'foobar' –

4

D'après ce que je comprends rechercher tout caractère qui précède par un caractère 3 length.SO il doit correspondre à « bbb », mais ce ne est pas

Non! Jetons un coup d'oeil de plus près ...

^  # The caret is an anchor which denotes "STARTS WITH" 
(?=  # lookahead 
    .  # wildcard match; the . matches any non-new-line character 
    {3} # quantifier; exactly 3 times 
    $  # dollar sign; I'm not sure if it will act as an anchor but if it did it would mean "THE END" 
)  # end of lookbehind 
.  # wildcard match; the . matches any non-new-line character 
*  # quantifier; any number of times, including 0 times 

Plusieurs problèmes:

  1. Le caret exige que le .* être les premiers caractères de la chaîne et que vous essayez de les lookbehind pour les caractères sandwhiched entre le début ^ et les premiers caractères .*.
  2. Votre .{3} signifie en fait tous les trois caractères, aucun caractère répété trois fois;) Vous voulez vraiment savoir How can I find repeated letters with a Perl regex?