0

I'm trying to create a regex that will meet the following requirements for a password.

  1. Must have at least 1 uppercase
  2. Must have at least 1 lowercase
  3. Must contain a number OR a symbol - FAILS
  4. Must be between 8 to 16 characters long

    ^(?=.*\d|[!@#\$%\^&])(?=.*[a-z])(?=.*[A-Z]).{8,16}$

I've got it working, well almost, except the OR part. It verifies for instance Tester01 and Tester0% but it wont verify Tester%$ or anything with two symbols, just in case the user doesn't put in a number. I've also tried putting brackets around the \d thinking I had to separate the digits from the symbols but that didn't work.

JK36
  • 853
  • 2
  • 14
  • 37

2 Answers2

0

Your alternation condition isn't correct. Instead you can just slide the \d within the special characters bracket and change your regex to this,

^(?=.*[\d!@#\$%\^&])(?=.*[a-z])(?=.*[A-Z]).{8,16}$

Now your this look ahead (?=.*[\d!@#\$%\^&]) behaves exactly as you wanted. It will ensure that either one character is any digit or the other special characters mentioned in your character class.

Demo

The reason why your look ahead (?=.*\d|[!@#\$%\^&]) fails is because your first alternation condition is .*\d and second is merely [!@#\$%\^&] where as if correctly written it should have been either this,

(?=.*\d|.*[!@#\$%\^&])

OR

(?=.*(\d|[!@#\$%\^&]))

And you really don't need alternation at all if you write it like the way I have written above, where you can just put \d within the character set itself, like this,

(?=.*([\d!@#\$%\^&]))
Pushpesh Kumar Rajwanshi
  • 18,127
  • 2
  • 19
  • 36
0

Use the principle of contrast with multiple lookaheads.

^
(?=[^A-Z]*[A-Z])
(?=[^a-z]*[a-z])
(?=[^\d!@#\$%\^&]*[^\d!@#\$%\^&])
.{8,16}
$

But please read this post as well (why password validations are bad?) and see a demo on regex101.com.

Jan
  • 42,290
  • 8
  • 54
  • 79