Estou criando um regexp para validação de senha para ser usado em um aplicativo Java como um parâmetro de configuração.
O regexp é:
^.*(?=.{8,})(?=..*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$
A política de senha é:
Pelo menos 8 caracteres
Contém pelo menos um dígito
Contém pelo menos um caractere alfa inferior e um caractere alfa superior
Contém pelo menos um caractere em um conjunto de caracteres especiais (
@#%$^
etc.)Não contém espaço, tabulação, etc.
Estou perdendo apenas o ponto 5. Não consigo fazer com que a regexp verifique se há espaço, tab, retorno de carro, etc.
Alguém pode ajudar-me?
Respostas:
Experimente isto:
Explicação:
É fácil adicionar, modificar ou remover regras individuais, uma vez que cada regra é um "módulo" independente.
A
(?=.*[xyz])
construção devora toda a string (.*
) e retrocede até a primeira ocorrência onde[xyz]
pode corresponder. É bem-sucedido se[xyz]
for encontrado, mas falha caso contrário.A alternativa seria utilizar um qualificador relutantes:
(?=.*?[xyz])
. Para uma verificação de senha, isso dificilmente fará qualquer diferença, para strings muito mais longas, poderia ser a variante mais eficiente.A variante mais eficiente (mas mais difícil de ler e manter, portanto, a mais sujeita a erros) seria
(?=[^xyz]*[xyz])
, é claro. Para uma regex desse tamanho e para essa finalidade, eu não recomendaria fazer dessa forma, pois não tem benefícios reais.fonte
\\s
. Esse é um requisito do Java, não um requisito do regex.(?=...)
padrão para que ele correspondesse à configuração do resto da expressão.(?=\S+$)
) ou "não contém caracteres de espaço" ((?!.*\s)
) é uma questão de preferência. Use o que você quiser melhor. :)exemplo simples usando regex
Explicações:
(?=.*[0-9])
um dígito deve ocorrer pelo menos uma vez(?=.*[a-z])
uma letra minúscula deve ocorrer pelo menos uma vez(?=.*[A-Z])
uma letra maiúscula deve ocorrer pelo menos uma vez(?=.*[@#$%^&+=])
um caractere especial deve ocorrer pelo menos uma vez(?=\\S+$)
nenhum espaço em branco permitido em toda a string.{8,}
pelo menos 8 caracteresfonte
Todas as respostas fornecidas anteriormente usam a mesma técnica (correta) para usar um lookahead separado para cada requisito. Mas eles contêm algumas ineficiências e um bug potencialmente enorme, dependendo do back-end que realmente usará a senha.
Vou começar com a regex da resposta aceita:
Em primeiro lugar, uma vez que o Java suporta
\A
e\z
eu prefiro usá-los para garantir que toda a string seja validada, independentemente dePattern.MULTILINE
. Isso não afeta o desempenho, mas evita erros quando os regexes são reciclados.Verificar se a senha não contém espaços em branco e verificar seu comprimento mínimo pode ser feito em uma única passagem usando o all de uma vez, colocando o quantificador de variável
{8,}
na abreviação\S
que limita os caracteres permitidos:Se a senha fornecida contiver um espaço, todas as verificações serão feitas, apenas para que a verificação final falhe no espaço. Isso pode ser evitado substituindo todos os pontos por
\S
:O ponto só deve ser usado se você realmente quiser permitir qualquer caractere. Caso contrário, use uma classe de caracteres (negada) para limitar sua regex apenas aos caracteres que são realmente permitidos. Embora faça pouca diferença neste caso, não usar o ponto quando algo mais for mais apropriado é um hábito muito bom. Vejo muitos casos de retrocesso catastrófico porque o desenvolvedor estava com preguiça de usar algo mais apropriado do que o ponto.
Como há uma boa chance de os testes iniciais encontrarem um caractere apropriado na primeira metade da senha, um quantificador lento pode ser mais eficiente:
Mas agora a questão realmente importante: nenhuma das respostas menciona o fato de que a pergunta original parece ter sido escrita por alguém que pensa em ASCII. Mas em Java, as strings são Unicode. Os caracteres não ASCII são permitidos nas senhas? Em caso afirmativo, apenas espaços ASCII não são permitidos ou todos os espaços em branco Unicode devem ser excluídos.
Por padrão,
\s
corresponde apenas a espaços em branco ASCII, portanto, seu inverso\S
corresponde a todos os caracteres Unicode (espaços em branco ou não) e todos os caracteres ASCII que não sejam de espaços em branco. Se os caracteres Unicode forem permitidos, mas os espaços Unicode não, oUNICODE_CHARACTER_CLASS
sinalizador pode ser especificado para\S
excluir os espaços em branco Unicode. Se os caracteres Unicode não forem permitidos, eles[\x21-\x7E]
podem ser usados em vez de\S
para corresponder a todos os caracteres ASCII que não sejam um espaço ou um caractere de controle.O que nos leva ao próximo problema potencial: queremos permitir personagens de controle? A primeira etapa para escrever uma regex adequada é especificar exatamente o que você deseja corresponder e o que não. A única resposta 100% tecnicamente correta é que a especificação da senha na pergunta é ambígua, porque não indica se determinados intervalos de caracteres, como caracteres de controle ou caracteres não ASCII, são permitidos ou não.
fonte
Você não deve usar Regex excessivamente complexo (se puder evitá-los) porque eles são
Embora possa haver uma pequena sobrecarga de desempenho no uso de muitas pequenas expressões regulares, os pontos acima superam isso facilmente.
Eu implementaria assim:
fonte
Requisito de senha:
As senhas devem incluir caracteres de pelo menos dois (2) desses agrupamentos: alfa, numérico e caracteres especiais.
Eu testei e funciona
fonte
Para qualquer pessoa interessada nos requisitos mínimos para cada tipo de personagem, sugiro fazer a seguinte extensão sobre a resposta aceita de Tomalak:
Observe que esta é uma string de formatação e não o padrão regex final. Basta substituir% d com as ocorrências mínimas necessárias para: dígitos, minúsculas, maiúsculas, não dígitos / caracteres e senha inteira (respectivamente). Ocorrências máximas são improváveis (a menos que você queira um máximo de 0, rejeitando efetivamente qualquer um desses caracteres), mas essas também podem ser facilmente adicionadas. Observe o agrupamento extra em torno de cada tipo, de modo que as restrições mín. / Máx. Permitam correspondências não consecutivas. Isso funcionou maravilhosamente bem para um sistema em que poderíamos configurar centralmente quantos de cada tipo de caractere exigíamos e, em seguida, fazer com que o site, bem como duas plataformas móveis diferentes buscassem essas informações, a fim de construir o padrão regex com base na string de formatação acima.
fonte
Este verifica todos os caracteres especiais:
fonte
Método Java pronto para você, com parâmetros
Basta copiar e colar e definir os parâmetros desejados.
Se você não quiser um módulo, apenas comente-o ou adicione um "se" como feito por mim para caractere especial
fonte
Use a biblioteca Passay , que é uma API poderosa.
fonte
Acho que isso também pode fazer (como um modo mais simples):
[Demo Regex]
fonte
Facil
("^ (? =. * [0-9]) (? =. * [Az]) (? =. * [AZ]) (? =. * [\\ W _]) [\\ S] {8 , 10} $ ")
(? = qualquer coisa) -> significa que o positivo olha para a frente em todas as strings de entrada e certifique-se de que esta condição seja escrita .sample (? =. * [0-9]) -> significa que um número de dígito é escrito em todas as strings. E se não escrito, retorna falso .
(?! qualquer coisa) -> (vice-versa) significa que negativo olha para a frente se a condição é escrita retorna falsa .
fechar significado ^ (condição) (condição) (condição) (condição) [\ S] {8,10} $
fonte
Explicação:
fonte
Também você pode fazer assim.
fonte
Bloco de código de amostra para senha forte:
fonte
RegEx é -
fonte