1

So i'm trying to create a Regex which does the following:

Min 12 Characters, Requires Uppercase, Requires Lowercase, Requires 2 Numeric values OR 2 Special Characters.

At the moment i have the following:

~^(?=\P{Ll}*\p{Ll})(?=\P{Lu}*\p{Lu})(?=.*[!@#$%^&*()]|\D*\d).{12,}~u

Which does 1 numeric OR 1 special character, not 2. I've tried adding {2} to the OR condition, however, this requires a combination of two which is incorrect.

Any help would be appreciated.

Jordan Lowe
  • 368
  • 1
  • 13

1 Answers1

1

You should replace (?=.*[!@#$%^&*()]|\D*\d) lookahead with (?:(?=(?:[^!@#$%^&*()]*[!@#$%^&*()]){2})|(?=(?:\D*\d){2})). The regex will look like

'~^(?=\P{Ll}*\p{Ll})(?=\P{Lu}*\p{Lu})(?:(?=(?:[^!@#$%^&*()]*[!@#$%^&*()]){2})|(?=(?:\D*\d){2})).{12,}$~u'

See the regex demo.

The lookahead matches a location that is immediately followed with

  • (?:[^!@#$%^&*()]*[!@#$%^&*()]){2} - two repetitions of any 0+ chars other than !@#$%^&*() chars followed with a char from the !@#$%^&*() list
  • | - or
  • (?=(?:\D*\d){2} - two repetitions of any 0+ non-digit chars followed with a digit
Wiktor Stribiżew
  • 484,719
  • 26
  • 302
  • 397
  • That's perfect mate. I don't quite understand "(?:(?=(?:" but it works as expected. – Jordan Lowe Feb 21 '19 at 09:49
  • @JordanLowe You are using lookaheads in your regex, so I assumed you know what they mean. `(?:...)` is a [non-capturing group](https://stackoverflow.com/questions/3512471) that is good for quantifying sequences of pattenrs (see where `{2}` are placed, right after them). – Wiktor Stribiżew Feb 21 '19 at 09:51