Como verificar se a string possui pelo menos uma letra, número e caractere especial em php

Atualmente escrevo um pequeno script que verifica o conteúdo de cada string.

Eu queria saber o que o REGEX seria para garantir que uma string tenha uma letra (superior ou inferior), um dígito e um caractere especial?

Aqui está o que eu sei até agora (o que não é muito):

if(preg_match('/^[a-zA-Z0-9]+$/i', $string)): 

A ajuda seria excelente!

Obrigado!

O modo mais fácil (e provavelmente o melhor) é fazer três verificações separadas com preg_match :

 $containsLetter = preg_match('/[a-zA-Z]/', $string); $containsDigit = preg_match('/\d/', $string); $containsSpecial = preg_match('/[^a-zA-Z\d]/', $string); // $containsAll = $containsLetter && $containsDigit && $containsSpecial 

Você pode usar lookahead positivo para criar uma única regex:

 $strongPassword = preg_match('/^(?=.*[az])(?=.*[AZ])(?=.*\d)(?=.*[$%^&]).*$/'); // special characters ^^^^ 

Encontrei uma ótima resposta aqui com explicação para garantir que uma determinada string contenha pelo menos um caractere de cada uma das seguintes categorias.

Caráter em minúsculas, Caracteres maiúsculos, Dígito, Símbolo

 ^(?=.*[az])(?=.*[AZ])(?=.*\d)(?=.*(_|[^\w])).+$ 

Uma breve explicação:

^ // o início da string

(?=.*[az]) // use um olhar positivo para ver se existe pelo menos uma letra minúscula

(?=.*[AZ]) // use um olhar positivo para ver se existe pelo menos uma letra maiúscula

(?=.*\d) // use um olhar positivo para ver se existe pelo menos um dígito

(?=.*[_\W]) // use um olhar positivo para ver se pelo menos um caractere de sublinhado ou não-palavra existe

.+ // engolir toda a corda

$ // o fim da string

Espero que ajude você.

Pode ser melhor usar 3 regexs distintos para fazer isso, pois você precisaria combinar 6 possibilidades diferentes, dependendo de onde seus caracteres especiais estão em sua string. Mas se você quiser fazê-lo em um regex, e seus personagens especiais são, digamos, [+? @], É possível:

 $string = "abc@123"; $regex = "/^(?=.*[az])(?=.*[AZ])(?=.*\d)(?=.*[$%^&]).*$/" if (preg_match($regex, $string)) { // special characters } 

Uma letra é \pL , um número é \pN e um caractere especial é [what you want] , aqui eu suponho que não é uma letra e não um número, então o regex parece:

 /^(?=.*?\pL)(?=.*?\pN)(?=.*[^\pL\pN])/ 

Falso (resposta escolhida acima – Obrigado!) Teve a maneira muito simples de envolver sua cabeça em torno dela (se você não está muito familiarizado com a regex) e venha com o que funciona para você.

Acabei de colocar isso para elaborar um pouco:

(você pode colá-lo em http://phptester.net/index.php?lang=en para trabalhar com ele)

 < ?php $pass="abc1A"; $ucl = preg_match('/[AZ]/', $pass); // Uppercase Letter $lcl = preg_match('/[az]/', $pass); // Lowercase Letter $dig = preg_match('/\d/', $pass); // Numeral $nos = preg_match('/\W/', $pass); // Non-alpha/num characters (allows underscore) if($ucl) { echo "Contains upper case!
"; } if($lcl) { echo "Contains lower case!
"; } if($dig) { echo "Contains a numeral!
"; } // I negated this if you want to dis-allow non-alphas/num: if(!$nos) { echo "Contains no Symbols!
"; } if ($ucl && $lcl && $dig && !$nos) { // Negated on $nos here as well echo "
All Four Pass!!!"; } else { echo "
Failure..."; } ?>