0

Trying to get my regular expression to work for these rules:

  • Total atleast 8 characters long.
  • No larger than 21.
  • Should contain atleast two Uppercase
  • Should contain atleast two lowercase
  • Should contain atleast two numbers
  • Should contain atleast two of these symbols !@#$%^&*()
  • All characters can be in any permutation, do not have to be in repeated sequence.
  • (Added with Edit) Cannot can contain any other character not specified above.

I think this regular expression is close but does not work correctly.

/^(?=(?:\D*\d){2,}\D*$)(?=(?:[^a-z]*[a-z]){2,}[^a-z]*$)(?=(?:[^A-Z]*[A-Z]){2,}[^A-Z]*$)(?=(?:[^!@#$%^&*]*[!@#$%^&*]){2,}[^!@#$%^&*]*$)[a-zA-Z0-9!@#$%^&*]{8,21}$/

Norman Potts
  • 81
  • 1
  • 12
  • 2
    From my point of view, you can just iterate the string and check the rules one by one. Regex doesn't seem to be better than that. – Lancelod Liu Dec 26 '18 at 03:07
  • 1
    [I have a problem. I should use Regex. Now I have two problems.](https://blog.codinghorror.com/regular-expressions-now-you-have-two-problems/) – Erik Philips Dec 26 '18 at 03:10
  • You might benefit from reading [Reference - Password Validation](https://stackoverflow.com/questions/48345922/reference-password-validation) – ctwheels Dec 28 '18 at 19:19
  • @ctwheels Its not a password validation. Its a safety check for before database. – Norman Potts Dec 28 '18 at 23:09

2 Answers2

1

Use lookaheads with proper syntax:

^(?=.*[A-Z].*[A-Z])(?=.*[a-z].*[a-z])(?=.*[0-9].*[0-9])(?=.*[!@#$%^&*()].*[!@#$%^&*()])[a-zA-Z0-9!@#$%^&*]{8,21}$

As an example of what you were doing:

(?=(?:[^a-z]*[a-z]){2,}[^a-z]*$)

This says to match from the start of the password any number of non lowercase followed by a lowercase, the same lookahead twice. Keep in mind that lookaheads assert but do not match or move, so you were just checking for one lowercase twice. To check for at least two lowercase letters use:

(?=.*[a-z].*[a-z])

This checks for two lowercase letters anywhere in the password.

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • Thanks for the help. The regular expression needed to allow only [a-zA-Z0-9!@#$%^&*()] in it as well. The regular expression i came up with now is ^(?=.*[A-Z].*[A-Z])(?=.*[a-z].*[a-z])(?=.*[0-9].*[0-9])(?=.*[!@#$%^&*()].*[!@#$%^&*()])[a-zA-Z0-9!@#$%^&*]{8,21}$ – Norman Potts Dec 26 '18 at 03:53
1

I will go out on a limb and guess you have been asked to "produce the regex that will validate the application's password".

1) Read Password Rules Are Bullshit. See if you can convince your lead, team, or client to change these rules (gross). In particular, bump the max length up to at least 32 and drop the other rules.

2) I already know you probably can't do that, so at least make it so your application can clearly explain which password rule was broken. Make each rule a separate check you perform (like Lancelod suggested), in order, with a clear user-facing failure message for each.

3) If you can do that you might not even need a regex for that specific rule - sometimes a classic string scan is simpler and usually much faster.

Elliot Nelson
  • 11,371
  • 3
  • 30
  • 44
  • yea... um.. I'm just trying to get a prototype working and might sell the app or keep it in my portfolio. Its for a small team of around 5 members. For this use case its most appropriate to make a simple password check. If it ever gets implemented, the use case might get changed. – Norman Potts Dec 26 '18 at 03:44
  • And its not for password validation but you are close. – Norman Potts Dec 26 '18 at 03:50
  • Ah, in that case, scratch #1. – Elliot Nelson Dec 26 '18 at 03:59