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:
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?
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 }? .
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".
$ means "Match the end of the string" (the position after the last character in the string).
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:
This regex will fail if the entire string (because of the $
in the negative lookahead) contains only characters from any of the above groups.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With