Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regular Expression matching at least n of m groups

I was going to write a regular expression that would match only if a string contains at least n different classes of characters. I was going to use this to force my users to create strong passwords and wanted to check if the password contains at least 3 of the following:

  • Characters
  • Capital Characters
  • Numbers
  • Special Characters

Writing a regular expression that matches if all of those classes are present is trivial using lookaheads. However, I cannot wrap my head around the "at least 3" part. Is this even possible (in a nice, compact expression) or would I have to create a monster expression?

like image 996
Daniel Baulig Avatar asked Jul 18 '11 21:07

Daniel Baulig


People also ask

Which pattern matches the preceding pattern at least n times but not more than m times?

The { n , m } quantifier matches the preceding element at least n times, but no more than m times, where n and m are integers. { n , m } is a greedy quantifier whose lazy equivalent is { n , m }? .

How do I match a group in regex?

Capturing groups are a way to treat multiple characters as a single unit. They are created by placing the characters to be grouped inside a set of parentheses. For example, the regular expression (dog) creates a single group containing the letters "d", "o", and "g".

What does '$' mean in regex?

$ means "Match the end of the string" (the position after the last character in the string).


1 Answers

I think this will be more compact than listing each possible combination of 3 of the 4. It utilizes negative lookahead to make sure that the entire string is not composed of only one or two of the character classes you listed:

(?!([a-zA-Z]*|[a-z\d]*|[^A-Z\d]*|[A-Z\d]*|[^a-z\d]*|[^a-zA-Z]*)$).*

In order, the groups here are:

  • lower and/or upper
  • lower and/or digits
  • lower and/or special
  • upper and/or digits
  • upper and/or special
  • digits and/or special

This regex will fail if the entire string (because of the $ in the negative lookahead) contains only characters from any of the above groups.

like image 154
Andrew Clark Avatar answered Oct 08 '22 16:10

Andrew Clark