RegEx para asegurarse de que la cadena contiene al menos un carácter en minúsculas, caracteres en mayúsculas, dígitos y símbolos

156

¿Cuál es la expresión regular para asegurarse de que una cadena dada contiene al menos un carácter de cada una de las siguientes categorías?

  • Minúscula
  • Carácter en mayúscula
  • Dígito
  • Símbolo

Sé que las pautas de conjuntos individuales a saber [a-z], [A-Z], \dy _|[^\w](me dieron a corregir, ¿verdad?).

Pero, ¿cómo los combino para asegurarme de que la cadena contiene todos estos en cualquier orden?

Amarghosh
fuente
¿Qué plataforma / dialecto regex? La respuesta de Bart es correcta, pero las afirmaciones anticipadas no son confiables en JavaScript, por ejemplo.
bobince
En ninguna parte en particular, estoy aprendiendo regex. ¿Hay alguna alternativa que se pueda usar en javascript?
Amarghosh
@bobince Hola, estoy tratando de descubrir por qué las afirmaciones anticipadas no son confiables en Javascript. ¿Hay un informe sobre esto?
Chris Bier
@ChrisB: Hay un error de IE / JScript realmente confuso: blog.stevenlevithan.com/archives/regex-lookahead-bug
bobince

Respuestas:

349

Si necesita una única expresión regular, intente:

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

Una breve explicación:

(?=.*[a-z])        // use positive look ahead to see if at least one lower case letter exists
(?=.*[A-Z])        // use positive look ahead to see if at least one upper case letter exists
(?=.*\d)           // use positive look ahead to see if at least one digit exists
(?=.*\W])        // use positive look ahead to see if at least one non-word character exists

Y estoy de acuerdo con SilentGhost, \Wpodría ser un poco amplio. Lo reemplazaría con un conjunto de caracteres como este: [-+_!@#$%^&*.,?](¡no dude en agregar más, por supuesto!)

Bart Kiers
fuente
¿Qué pasaría si cambio el último .+en .*? No pude encontrar un caso de prueba que falla .*. ¿Son iguales en este contexto? "Cero o más caracteres" parece estar bien, solo busca confirmación.
Amarghosh
@Amarghosh: en este caso, no hay diferencia. Debido a la apariencia positiva, la cadena ya contiene al menos 4 caracteres. Así que no hay diferencia con el cambio .+en .*o incluso .{4,}para el caso.
Bart Kiers
Si está dispuesto a agregar una pequeña explicación, tengo problemas para entender cómo la combinación de estos lookaheads garantiza que al menos 1 de cada conjunto de caracteres estará presente
Sharlike
@Sharlike, no sé cómo reformularlo para que sea más fácil de entender. Especialmente en estos pequeños cuadros de comentarios. Le recomiendo que lea esto: regular-expressions.info/lookaround.html y si aún tiene alguna pregunta, simplemente publique una pregunta propia. ¡Buena suerte!
Bart Kiers
44
@ikertxu, prueba algo como esto:^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*[&%$]).{6,}$
Bart Kiers
20

Bart Kiers, tu expresión regular tiene un par de problemas. La mejor manera de hacerlo es esto:

(.*[a-z].*)       // For lower cases
(.*[A-Z].*)       // For upper cases
(.*\d.*)          // For digits

De esta manera, está buscando sin importar si al principio, al final o en el medio. En tu tengo muchos problemas con contraseñas complejas.

Juan Furattini
fuente
55
No está buscando símbolos como lo solicitó el OP.
Casimir
5

Puede unir esos tres grupos por separado y asegurarse de que todos estén presentes. Además, [^\w]parece un poco demasiado amplio, pero si eso es lo que quieres, puedes reemplazarlo \W.

SilentGhost
fuente
Gracias. No estaba al tanto de \ W. Solo busqué para encontrar que coincide con Not Word. ¿Hay alguna diferencia entre \ W y [\ W]? ¿Es [\ W] simplemente redundante?
Amarghosh el
@Amarghosh, sí, \Wy [\W]resulta en lo mismo.
Bart Kiers