2010-08-12 22 views
30

I tienen los siguientes criterios para la creación de una expresión regular para una contraseña que se ajusta a las siguientes reglas:expresión regular para hacer cumplir contraseñas complejas, a juego 3 de cada 4 reglas

  1. La contraseña debe ser de 8 caracteres de largo (esto puedo hacer :-)).

La contraseña debe entonces contener caracteres de al menos 3 de los siguientes 4 reglas:

  1. de caso superior
  2. Baja caso
  3. Números
  4. no alfanumérico

Puedo hacer que la expresión coincida con TODAS esas reglas con la siguiente expresión:

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

Pero estoy luchando con la forma de hacer esto de tal manera que sólo se necesita resolver cualquier 3 de las 4 reglas.

¿Alguien puede ayudarme con esto?

+7

tengo que decir que este es uno de esos casos cuando pienso en su código, probablemente sería mucho más legible si tuviera 4 expresiones regulares diferentes en su lugar. Y luego quizás haya un recuento y para cada una de las expresiones regulares que coincida, incremente el conteo y luego al final solo verifique si el conteo es 3 o más. –

+0

¿Qué lenguaje de programación estás usando? – kennytm

Respuesta

73

No utilice una expresión regular para comprobarlo en ese momento.

if (password.length < 8) 
    alert("bad password"); 
var hasUpperCase = /[A-Z]/.test(password); 
var hasLowerCase = /[a-z]/.test(password); 
var hasNumbers = /\d/.test(password); 
var hasNonalphas = /\W/.test(password); 
if (hasUpperCase + hasLowerCase + hasNumbers + hasNonalphas < 3) 
    alert("bad password"); 

Si tiene que usar una sola expresión regular:

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

Esta expresión regular no está optimizado para la eficiencia. Está construido por A·B·C + A·B·D + A·C·D + B·C·D con alguna factorización. Desglose:

^ 
(?: 
    (?=.*[a-z])  # 1. there is a lower-case letter ahead, 
    (?:    # and 
     (?=.*[A-Z]) #  1.a.i) there is also an upper-case letter, and 
     (?=.*[\d\W]) #  1.a.ii) a number (\d) or symbol (\W), 
    |     # or 
     (?=.*\W)  #  1.b.i) there is a symbol, and 
     (?=.*\d)  #  1.b.ii) a number ahead 
    ) 
|      # OR 
    (?=.*\W)   # 2.a) there is a symbol, and 
    (?=.*[A-Z])  # 2.b) an upper-case letter, and 
    (?=.*\d)   # 2.c) a number ahead. 
) 
.{8,}     # the password must be at least 8 characters long. 
$ 
5

Usted podría escribir una expresión regular muy sofisticado para hacer eso. En cambio, sugeriría escribir cuatro expresiones regulares distintas, una para cada regla, y probarlas una a una, contando cuántas de ellas coincidían. Si tres de cuatro lo hicieron, acepte la contraseña.

1

Id sugiero hacer las comprobaciones por separado, y luego sumar las coincidencias.

(también no haría uso de una expresión regular en cualquiera de ellos, pero eso es sólo mi Punto de vista personal - a saber, que dificultan la legibilidad y generalmente están de una sola escritura de código)

3

Usted puede usar la siguiente expresión regular:

(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[@#$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[@#$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$)? 

con una longitud mínima de la contraseña de 8 y una longitud máxima de 32 se puede utilizar la siguiente expresión regular:

(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,32}$)?(^(?=.*\d)(?=.*[a-z])(?=.*[@#$%^&+=]).{8,32}$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[@#$%^&+=]).{8,32}$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).{8,32}$)? 
+0

De cuatro, debe tomar 3 a la vez y si alguno de ellos coincide con el patrón de contraseña será validado. – ajithparamban

+3

¿Por qué establecer una longitud máxima de contraseña? – evolutionxbox

Cuestiones relacionadas