RegEx para garantir que a sequência contenha pelo menos um caractere minúsculo, caractere maiúsculo, dígito e símbolo

156

Qual é o regex para garantir que uma determinada sequência contenha pelo menos um caractere de cada uma das seguintes categorias.

  • Caracter em minúsculas
  • Caractere maiúsculo
  • Dígito
  • Símbolo

Eu sei que os padrões para conjuntos individuais ou seja [a-z], [A-Z], \de _|[^\w](eu tenho-os corrigir, não é?).

Mas como combiná-los para garantir que a string contenha tudo isso em qualquer ordem?

Amarghosh
fonte
Qual plataforma / dialeto regex? A resposta de Bart está certa, mas as asserções completas não são confiáveis ​​em JavaScript, por exemplo.
bobince
Em nenhum lugar em particular - estou aprendendo regex. Existe uma alternativa que possa ser usada em javascript?
Amarghosh 14/10/09
@bobince Ei, estou tentando descobrir por que as declarações de lookahead não são confiáveis ​​em Javascript. Existe um artigo sobre isso?
precisa
@ChrisB: Há um bug IE / JScript realmente confuso: blog.stevenlevithan.com/archives/regex-lookahead-bug
bobince

Respostas:

349

Se você precisar de uma única regex, tente:

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

Uma breve explicação:

(?=.*[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

E eu concordo com o SilentGhost, \Wpode ser um pouco amplo. Eu o substituiria por um conjunto de caracteres como este: [-+_!@#$%^&*.,?](fique à vontade para adicionar mais, é claro!)

Bart Kiers
fonte
O que aconteceria se eu mudar o último .+para .*? Não pude apresentar um caso de teste que falhe .*. Eles são iguais neste contexto? "Zero ou mais caracteres" parece estar bem - apenas buscando confirmação.
Amarghosh 14/10/09
@Amarghosh: neste caso, não faz diferença. Por causa das previsões positivas, a sequência já contém pelo menos 4 caracteres. Portanto, não faz diferença mudar .+para .*ou mesmo .{4,}para esse assunto.
22410 Bart Kiers
Se você estaria disposto a adicionar um pouco de explicação, eu estou tendo dificuldade para entender como a combinação desses lookaheads garantias pelo menos 1 de cada conjunto de caracteres estará presente
Sharlike
@ Shaharlike, não sei como reformulá-lo para facilitar a compreensão. Especialmente nessas pequenas caixas de comentários. Eu recomendo que você leia isto: regular-expressions.info/lookaround.html e se você ainda tiver alguma dúvida, basta postar uma pergunta sua. Boa sorte!
Bart Kiers
4
@ikertxu, tente algo como isto:^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*[&%$]).{6,}$
Bart Kiers
20

Bart Kiers, seu regex tem alguns problemas. A melhor maneira de fazer isso é:

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

Desta forma, você está pesquisando, não importa se no começo, no final ou no meio. No seu caso, tenho muitos problemas com senhas complexas.

Juan Furattini
fonte
5
Você não está verificando símbolos como o OP solicitou.
Casimir
5

Você pode combinar esses três grupos separadamente e verifique se todos estão presentes. Além disso, [^\w]parece um pouco amplo demais, mas se é isso que você deseja, poderá substituí-lo \W.

SilentGhost
fonte
Obrigado. Eu não estava ciente de \ W. Apenas procurei descobrir que ele não corresponde ao Word. Existe alguma diferença entre \ W e [\ W]? [\ W] é apenas redundante?
Amarghosh 14/10/09
@ Marghosh, sim, \We [\W]resultar no mesmo.
22426 Bart Kiers