2009-08-06 9 views
7

Entiendo las expresiones regulares razonablemente bien, pero no consigo hacer uso de ellas con la frecuencia suficiente como para ser un experto. Me encontré con una expresión regular que estoy usando para validar la contraseña, pero contiene algunos conceptos de expresiones regulares con los que no estoy familiarizado. La expresión regular es:Explicación de LookAheads en esta expresión regular

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

y en la llanura Inglés que significa que la cadena debe contener al menos un carácter en minúscula, un carácter en mayúscula y un número, y la cadena debe ser de al menos seis caracteres. ¿Alguien puede analizar esto para explicarme cómo este patrón realmente describe esa regla? Veo un inicio de string char^y un final de string char $, tres grupos con lookaheads, un match de cualquier carácter. y una repetición {6,}.

Gracias a cualquier gurú regex que pueda ayudarme a entender esto.

+0

Una cosa que te ayudará es obtener la terminología correcta. '\ d' coincide con un ** dígito **, y' [a-z] 'y' [A-Z] 'coincide ** letras **. Sé que muchas personas usan las palabras * número * y * carácter * en su lugar, pero es mucho menos probable que se le malinterprete si usa las palabras correctas. –

+0

Gracias a todos por las claras explicaciones. La explicación de que los lookaheads no consumen la cadena que se combina realmente ayudó a aclarar esto para mí. Gracias también por señalar que mi terminología debe ser más exacta. Acepto, a veces soy vago con mi terminología y me ayuda un cumplimiento más estricto. –

Respuesta

14

En circunstancias normales, una parte de una expresión regular coincide con una parte de la cadena de entrada, y "consume" esa parte de la cadena. La siguiente parte de la expresión coincide con la siguiente parte de la cadena, y así sucesivamente.

afirmaciones de búsqueda hacia delante no consumen cualquiera de la cadena, por lo que sus tres afirmaciones de búsqueda hacia delante:

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

cada uno significa "Este patrón (cualquier cosa seguida de un dígito, una letra minúscula, una letra mayúscula, respectivamente) Debe aparecer en algún lugar de la cadena", pero no mover los delanteros posición de coincidencia actuales, por lo que el resto de la expresión:

  • .{6,}

(que significa 'seis o más caracteres') todavía debe coincidir con la totalidad de la cadena de entrada.

-1

Las aserciones de anticipación se utilizan para garantizar que haya al menos un dígito, una letra minúscula y una letra mayúscula en la cadena.

5

El grupo de búsqueda anticipada no consume la entrada. De esta forma, los mismos personajes están siendo emparejados por los diferentes grupos de anticipación.

Puede pensarlo de esta manera: busque cualquier cosa (.*) hasta que encuentre un dígito (\d). Si lo hace, regrese al comienzo de este grupo (el concepto de búsqueda anticipada). Ahora busque cualquier cosa (.*) hasta que encuentre una letra minúscula. Repita para la letra mayúscula. Ahora, empareja 6 o más personajes.

4

Para descomponerlo por completo.

^ -- 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

fui y revisa para ver cómo esto se correspondería si se utiliza Perl:

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,}$" 

he modificado ligeramente la salida

+0

Gracias, Brad. Realmente ME DEJASte esto por mí. :-) Muy interesante. –

Cuestiones relacionadas