0

I need to create a regular expression with the next demands: Password need to have at least 8 characters and maximum 12 characters, at least 1 uppercase, at least 3 lowercase, at least 1 digit and at least 1 special character from the group (#*.!?$), without parentheses. The first character needs to be an uppercase or lowercase letter. Two consecutive same characters must not appear in the password. I made this, but it doesn't work:

^(?=.{8,12}$)(([a-z]|[A-Z])(?=.*\d){1,}(?=.*[a-z]){3,}(?=.*[A-Z]){1,}(?=.*[!.?*$#])\2?(?!\2))+$

I tried to test it with Abcd123!, but it doesn't work. Can anyone explain where did I make a mistake, and what I actually did here?

Toto
  • 89,455
  • 62
  • 89
  • 125

1 Answers1

2

You use a quantifier like {1,} for the lookahead which is not correct.

I think you meant to use the lookaheads like this:

^(?=.{8,12}$)(?=[^A-Z]*[A-Z])(?=\D*\d)(?=(?:[^a-z]*[a-z]){3})(?=[^\s#*.!?$]*[#*.!?$])(?!.*(.)\1)(?:[a-z]|[A-Z])[a-zA-Z0-9#*.!?$,]+$

About the pattern

  • ^ Start of the string
  • (?=.{8,12}$) Assert lenght 8 - 12
  • (?=[^A-Z]*[A-Z]) Assert an uppercase char
  • (?=\D*\d) Assert a digit
  • (?=(?:[^a-z]*[a-z]){3}) Assert 3 lowercase chars
  • (?=[^\s#*.!?$]*[#*.!?$]) Assert special char
  • (?!.*(.)\1) Assert not 2 consecutive chars
  • (?:[a-z]|[A-Z]) Start with upper or lowercase char
  • [a-zA-Z0-9#*.!?$,]+ Match 1+ times any of the listed in the character class
  • $ Assert end of the string

Regex demo | Php demo

The fourth bird
  • 154,723
  • 16
  • 55
  • 70
  • Unfortunately it still doesn't work. At first I tried the simplest regex with the length constraint and using uppercase, lowercase and digits and it worked, but it would be just 20% of the regex I need. – Miloš Mladenović Mar 23 '19 at 18:09
  • Which matches do not work? And what should the other 80% match? The lookaheads in the pattern match your requirements. You could add the the character class `[a-zA-Z0-9#*.!?$,]+` what you want to allow to match. – The fourth bird Mar 23 '19 at 19:03
  • The regex you provided does not work, I don't understand why. What you wrote is completely what I need, it just probably needs some modifications in order to work. Those 20% were what I previously made, some basic regex. – Miloš Mladenović Mar 23 '19 at 19:07
  • This is the code that worked ` $uppercase = preg_match('@[A-Z]@', $pass); $lowercase = preg_match('@[a-z]@', $pass); $number = preg_match('@[0-9]@', $pass); ` and this is what doesn't work ` $pattern = '/^(?=.{8,12}$)(?=.*[A-Z])(?=.*\d)(?=(?:.*[a-z]))(?=.*[#*.!?$])(?!.*(.)\1)(?:[a-z]|[A-Z])[a-zA-Z0-9#*.!?$,]+$/'; $regex = preg_match($pattern, $pass); ` – Miloš Mladenović Mar 23 '19 at 19:22
  • @MilošMladenović Sorry for my late response. I have created 2 examples where the pattern works for me in php. See https://3v4l.org/5Z8db Can you let me know if those also work for you? – The fourth bird Mar 24 '19 at 08:30
  • Everything is ok, thanks a lot for your help! I didn't answer right away because I was trying to find an error in my code. Your first regex is also good (I checked it via online regex validator), but for some reason preg_match in my code always returns 0, so it does not enter if conditional and of course does not write anything into database. My logic looks like this: – Miloš Mladenović Mar 27 '19 at 18:30
  • I will mark your first answer. If you could see where have I mistaken in logic, it would be of great help: $regex = preg_match('/^(?=.{8,12}$)(?=.*[A-Z])(?=.*\d)(?=(?:.*[a-z]){3})(?=.*[#*.!?$])(?!.*(.)\1)(?:[a-z]|[A-Z])[a-zA-Z0-9#*.!?$,]+$/m', $pass); if($regex) {// write into database}; – Miloš Mladenović Mar 27 '19 at 18:38
  • @MilošMladenović This is an example using your code and from what I can see is that is works https://3v4l.org/9vrDk Do you have an example of a string for which it fails? – The fourth bird Mar 27 '19 at 18:45
  • I tried with "Abcd1234!", for example. Can md5 function cause a trouble? – Miloš Mladenović Mar 27 '19 at 18:58
  • 1
    I found an error: I shouldn't put $_POST into md5 function because it generates a lot of characters which do not match with my constraint od 12 characters. I just used md5 function when writing into database and it worked.@The fourth bird, once again, thanks a lot for your help! – Miloš Mladenović Mar 27 '19 at 19:20