2009-08-06 3 views
7

Ich verstehe reguläre Ausdrücke einigermaßen gut, aber ich kann sie nicht oft genug nutzen, um ein Experte zu sein. Ich bin über einen regulären Ausdruck gestolpert, den ich verwende, um die Passwortstärke zu überprüfen, aber er enthält einige Regex-Konzepte, mit denen ich nicht vertraut bin. Die regulären Ausdruck ist:Erklärung der Lookaheads in diesem regulären Ausdruck

^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}$ 

und in Klartext heißt das, dass die Zeichenfolge mindestens einen Kleinbuchstaben, einen Großbuchstaben enthalten, und eine Zahl, und die Zeichenfolge muss mindestens sechs Zeichen lang sein. Kann mir jemand das erklären, um zu erklären, wie dieses Muster diese Regel tatsächlich beschreibt? Ich sehe einen Anfang von Zeichenkette char^und ein Ende von Zeichenkette char $, drei Gruppen mit Lookaheads, eine Übereinstimmung mit einem beliebigen Zeichen. und eine Wiederholung {6}.

Danke an jeden Regex-Guru, der mir helfen kann, meinen Kopf um diese zu bekommen.

+0

Eine Sache, die Ihnen helfen wird, die Terminologie richtig zu machen. '\ d' entspricht einer ** Ziffer **, und' [a-z] 'und' [A-Z] 'entsprechen ** Buchstaben **. Ich weiß, dass viele Leute die Wörter * number * und * character * verwenden, aber Sie werden viel weniger falsch verstanden, wenn Sie die richtigen Worte verwenden. –

+0

Danke an alle für die sehr klaren Erklärungen. Die Erklärung, dass die Lookaheads die gefundene Zeichenfolge nicht konsumieren, hat mir wirklich geholfen, dies zu klären. Danke auch für den Hinweis, dass meine Terminologie genauer sein muss - ich stimme zu, ich bin manchmal faul mit meiner Terminologie und eine strengere Einhaltung wird helfen. –

Antwort

14

Unter normalen Umständen entspricht ein Teil eines regulären Ausdrucks einem Teil der Eingabezeichenfolge und "konsumiert" dieses Teil der Zeichenfolge. Der nächste Teil des Ausdrucks stimmt mit dem nächsten Teil der Zeichenfolge überein und so weiter.

Die Look-Ahead Behauptungen nicht verbrauchen jede der Saite, so dass Ihre drei Look-Ahead-Behauptungen:

  • (?=.*\d)
  • (?=.*[a-z])
  • (?=.*[A-Z])

jeweils bedeuten „Dieses Muster (alles gefolgt von einer Ziffer, einem Kleinbuchstaben bzw. einem Großbuchstaben) Muss irgendwo in der Zeichenfolge“, aber sie haben nicht die aktuelle Spiel Position nach vorne, so dass der Rest des Ausdrucks bewegen:

  • .{6,}

(das bedeutet‚erscheinen sechs oder mehr Zeichen‘) muss immer noch mit der gesamten Eingabezeichenfolge übereinstimmen.

-1

Die Look-Ahead-Assertions werden verwendet, um sicherzustellen, dass in der Zeichenfolge mindestens eine Ziffer, ein Kleinbuchstabe und ein Großbuchstabe enthalten sind.

5

Die Lookahead-Gruppe verbraucht die Eingabe nicht. Auf diese Weise werden die gleichen Zeichen tatsächlich von den verschiedenen Lookahead-Gruppen verglichen.

Sie können auf diese Weise denken: Suchen Sie nach etwas (.*), bis Sie eine Ziffer finden (\d). Wenn Sie dies tun, gehen Sie zurück zum Anfang dieser Gruppe (das Konzept des Lookahead). Suchen Sie nun nach etwas (.*), bis Sie einen Kleinbuchstaben finden. Wiederholen Sie für Großbuchstaben. Passe jetzt 6 oder mehr Zeichen an.

4

Um es komplett zu brechen.

^ -- Match beginning of line 
(?=.*\d) -- The following string contains a number 
(?=.*[a-z]) -- The following string contains a lowercase letter 
(?=.*[A-Z]) -- The following string contains an uppercase letter 
.{6,} -- Match at least 6, as many as desired of any character 
$ -- Match end of line 
1

Ich ging hin und geprüft, um zu sehen, wie dies bei Verwendung von Perl würde passen:

perl -Mre=debug -E'q[ abc 345 DEF ]=~/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}$/' 

Compiling REx "^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}$" 
synthetic stclass "ANYOF[\0-\11\13-\377{unicode_all}]". 
Final program: 
    1: BOL (2) 
    2: IFMATCH[0] (9) 
    4: STAR (6) 
    5:  REG_ANY (0) 
    6: DIGIT (7) 
    7: SUCCEED (0) 
    8: TAIL (9) 
    9: IFMATCH[0] (26) 
    11: STAR (13) 
    12:  REG_ANY (0) 
    13: ANYOF[a-z] (24) 
    24: SUCCEED (0) 
    25: TAIL (26) 
    26: IFMATCH[0] (43) 
    28: STAR (30) 
    29:  REG_ANY (0) 
    30: ANYOF[A-Z] (41) 
    41: SUCCEED (0) 
    42: TAIL (43) 
    43: CURLY {6,32767} (46) 
    45: REG_ANY (0) 
    46: EOL (47) 
    47: END (0) 

floating ""$ at 6..2147483647 (checking floating) stclass ANYOF[\0-\11\13-\377{unicode_all}] anchored(BOL) minlen 6 
Guessing start of match in sv for REx "^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}$" against " abc 345 DEF " 
Found floating substr ""$ at offset 16... 
start_shift: 6 check_at: 16 s: 0 endpos: 11 
Does not contradict STCLASS... 
Guessed: match at offset 0 
Matching REx "^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}$" against " abc 345 DEF " 
    0 <> < abc 345>   | 1:BOL(2) 
    0 <> < abc 345>   | 2:IFMATCH[0](9) 
    0 <> < abc 345>   | 4: STAR(6) 
            REG_ANY can match 16 times out of 2147483647... 
    16 <c 345 DEF > <>  | 6: DIGIT(7) # failed... 
    15 <c 345 DEF > < >  | 6: DIGIT(7) # failed... 
    14 <c 345 DEF> < >  | 6: DIGIT(7) # failed... 
    13 <c 345 DE> <F >  | 6: DIGIT(7) # failed... 
    12 <c 345 D> <EF >  | 6: DIGIT(7) # failed... 
    11 <c 345 > <DEF >  | 6: DIGIT(7) # failed... 
    10 <c 345> <DEF>  | 6: DIGIT(7) # failed... 
    9 <c 34> <5 DEF >  | 6: DIGIT(7) 
    10 <c 345> <DEF>  | 7: SUCCEED(0) 
             subpattern success... 
    0 <> < abc 345>   | 9:IFMATCH[0](26) 
    0 <> < abc 345>   | 11: STAR(13) 
            REG_ANY can match 16 times out of 2147483647... 
    16 <c 345 DEF > <>  | 13: ANYOF[a-z](24) # failed... 
    15 <c 345 DEF > < >  | 13: ANYOF[a-z](24) # failed... 
    14 <c 345 DEF> < >  | 13: ANYOF[a-z](24) # failed... 
    13 <c 345 DE> <F >  | 13: ANYOF[a-z](24) # failed... 
    12 <c 345 D> <EF >  | 13: ANYOF[a-z](24) # failed... 
    11 <c 345 > <DEF >  | 13: ANYOF[a-z](24) # failed... 
    10 <c 345> <DEF>  | 13: ANYOF[a-z](24) # failed... 
    9 <c 34> <5 DEF >  | 13: ANYOF[a-z](24) # failed... 
    8 <bc 3> <45 DEF >  | 13: ANYOF[a-z](24) # failed... 
    7 <abc > <345 DEF >  | 13: ANYOF[a-z](24) # failed... 
    6 <abc> < 345 DEF > | 13: ANYOF[a-z](24) # failed... 
    5 < abc> < 345 DEF > | 13: ANYOF[a-z](24) # failed... 
    4 < ab> <c 345 DEF>  | 13: ANYOF[a-z](24) 
    5 < abc> < 345 DEF > | 24: SUCCEED(0) 
             subpattern success... 
    0 <> < abc 345>   | 26:IFMATCH[0](43) 
    0 <> < abc 345>   | 28: STAR(30) 
            REG_ANY can match 16 times out of 2147483647... 
    16 <c 345 DEF > <>  | 30: ANYOF[A-Z](41) # failed... 
    15 <c 345 DEF > < >  | 30: ANYOF[A-Z](41) # failed... 
    14 <c 345 DEF> < >  | 30: ANYOF[A-Z](41) # failed... 
    13 <c 345 DE> <F >  | 30: ANYOF[A-Z](41) 
    14 <c 345 DEF> < >  | 41: SUCCEED(0) 
             subpattern success... 
    0 <> < abc 345>   | 43:CURLY {6,32767}(46) 
            REG_ANY can match 16 times out of 2147483647... 
    16 <c 345 DEF > <>  | 46: EOL(47) 
    16 <c 345 DEF > <>  | 47: END(0) 
Match successful! 
Freeing REx: "^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}$" 

ich leicht die Ausgabe geändert

+0

Danke, Brad. Du hast das wirklich kaputt gemacht. :-) Sehr interessant. –