Regular expression supporting at least two of the four conditions

Asked

Viewed 697 times

5

I am writing a regular expression for password validation.

I wanted to know the easiest way to get a regular expression to accept, at the very least, two of these conditions:

  1. Capital letters
  2. Lowercase letters
  3. Special characters
  4. Numbers

Right now, I have the following regular expression:

"(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{4,20}";

in which:

(?=.*\\d): Accept at least one number.
(?=.*[a-z]): Accept at least one lower case letter.
(?=.*[A-Z]): Accept at least one capital letter.
(?=.*[@#$%]): Accept at least one symbol.
{4,20}: Password between 4 and 20 characters.

The problem is that in order for the password to pass this validation process, the password will have to have obligatorily one of these symbols. That is, a password must have a number, a lowercase letter, a capital letter and a symbol.

What I want is for the password to respect two or more conditions.

Example:

  • A password with a lowercase letter and a symbol is accepted (goes from meeting the two conditions).
  • A password with a lowercase letter, a capital letter and a symbol is also accepted.
  • A lowercase only password is not accepted.

2 answers

4


This one works:

^(?!^([a-z]+|[A-Z]+|\d+|[\W_]+)$).{4,20}$

Testing: https://regex101.com/r/G4v9oy/7

When entering the site, in the right panel, a detailed explanation about regex is also offered.

EDITED: I noticed some unnecessary things and simplified the expression. The test link has been updated.

  • Test with ______.

  • Thank you, @Guilhermelautert . I’ve updated my reply to also cover these other special characters.

  • 2

    Tip: when you are working with anchors not the need for poles between brackets, [\d]+ suffice \d+. Second you could have used only (\W|_)+. And out of curiosity there is also the class Posix [:alnum:], getting [^[:alnum:]]+

0

Try it like this:

(?:.*[a-z].*[^a-z])|(?:.*[A-Z].*[^A-Z])|(?:.*[0-9].*[^0-9])|(?:.*[^0-9A-Za-z].*[0-9A-Za-z])

Explanation:

  • (?:.*[a-z].*[^a-z]) - Any string that has a lower-case letter somewhere followed by something other than a lower-case letter.

  • (?:.*[A-Z].*[^A-Z]) - Any string that has an uppercase letter somewhere followed by something other than an uppercase letter.

  • (?:.*[0-9].*[^0-9]) - Any string that has a digit somewhere followed by something other than a digit.

  • (?:.*[^0-9A-Za-z].*[0-9A-Za-z]) - Any string that has a symbol followed by something other than a symbol.

As a symbol, we understand something that is neither uppercase, lowercase, nor digit.

All these parts are joined with the |. That is, it has to fall in any of the above cases.

  • Thank you for the suggestion, and I understand its logic. However, it does not pass the tests: https://regex101.com/r/FkGrXA/1

Browser other questions tagged

You are not signed in. Login or sign up in order to post.