RegEx pour vous assurer que la chaîne contient au moins un caractère minuscule, un caractère majuscule, un chiffre et un symbole

156

Quelle est l'expression régulière pour s'assurer qu'une chaîne donnée contient au moins un caractère de chacune des catégories suivantes.

  • Caractère minuscule
  • Caractère majuscule
  • Chiffre
  • symbole

Je sais que les modèles pour des jeux individuels à savoir [a-z], [A-Z], \det _|[^\w](j'ai eu les corriger, non?).

Mais comment puis-je les combiner pour m'assurer que la chaîne contient tout cela dans n'importe quel ordre?

Amarghosh
la source
Quelle plate-forme / quel dialecte regex? La réponse de Bart est juste, mais les affirmations d'anticipation ne sont pas fiables en JavaScript, par exemple.
bobince
Nulle part en particulier - j'apprends les regex. Existe-t-il une alternative utilisable en javascript?
Amarghosh
@bobince Hé, j'essaye de découvrir pourquoi les assertions lookahead ne sont pas fiables en Javascript. Y a-t-il un écrit à ce sujet?
Chris Bier
@ChrisB: Il y a un bogue IE / JScript vraiment déroutant: blog.stevenlevithan.com/archives/regex-lookahead-bug
bobince

Réponses:

349

Si vous avez besoin d'une seule expression régulière, essayez:

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

Une brève explication:

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

Et je suis d'accord avec SilentGhost, \Wpourrait être un peu large. Je le remplacerais par un jeu de caractères comme celui-ci: [-+_!@#$%^&*.,?](n'hésitez pas à en ajouter bien sûr!)

Bart Kiers
la source
Que se passerait-il si je change le dernier .+en .*? Je n'ai pas pu trouver un cas de test qui échoue .*. Sont-ils identiques dans ce contexte? "Zéro caractères ou plus" semble être bien - il suffit de chercher une confirmation.
Amarghosh
@Amarghosh: dans ce cas, cela ne fait aucune différence. En raison des perspectives positives, la chaîne contient déjà au moins 4 caractères. Cela ne fait donc aucune différence de changer .+en .*ou même .{4,}d'ailleurs.
Bart Kiers
Si vous êtes prêt à ajouter une petite explication, j'ai du mal à comprendre comment la combinaison de ces lookaheads garantit au moins 1 de chaque jeu de caractères sera présent
Sharlike
@Sharlike, je ne sais pas comment le reformuler pour le rendre plus facile à comprendre. Surtout dans ces petites boîtes de commentaires. Je vous recommande de lire ceci: regular-expressions.info/lookaround.html et si vous avez encore des questions, postez simplement votre propre question. Bonne chance!
Bart Kiers
4
@ikertxu, essayez quelque chose comme ceci:^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*[&%$]).{6,}$
Bart Kiers
20

Bart Kiers, votre regex a quelques problèmes. La meilleure façon de procéder est la suivante:

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

De cette façon, vous recherchez que ce soit au début, à la fin ou au milieu. Dans votre cas, j'ai beaucoup de problèmes avec les mots de passe complexes.

Juan Furattini
la source
5
Vous ne vérifiez pas les symboles comme l'OP l'a demandé.
Casimir
5

Vous pouvez faire correspondre ces trois groupes séparément et vous assurer qu'ils sont tous présents. De plus, cela [^\w]semble un peu trop large, mais si c'est ce que vous voulez, vous voudrez peut-être le remplacer \W.

SilentGhost
la source
Merci. Je n'étais pas au courant de \ W. Il suffit de le rechercher pour trouver qu'il correspond à Not Word. Y a-t-il une différence entre \ W et [\ W]? Est-ce que [\ W] est simplement redondant?
Amarghosh
@Amarghosh, oui, \Wet le [\W]résultat est le même.
Bart Kiers