In password strategy, there are 4 requirements. It should contains any three of the following
The following regex will match all cases
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{4,8}$
I know I can use '|' to declare all combinations, however, that will produce a supper long regex. What is the best way to replace '|' so that it can check if the input contains any of three conditions in the combination?
To match a character having special meaning in regex, you need to use a escape sequence prefix with a backslash ( \ ). E.g., \. matches "." ; regex \+ matches "+" ; and regex \( matches "(" . You also need to use regex \\ to match "\" (back-slash).
(?= regex_here) is a positive lookahead. It is a zero-width assertion, meaning that it matches a location that is followed by the regex contained within (?=
Short for regular expression, a regex is a string of text that lets you create patterns that help match, locate, and manage text. Perl is a great example of a programming language that utilizes regular expressions.
If you're using a PCRE flavor, the following one could suit your needs (formatted for readability):
^(?:
((?=.*\d))((?=.*[a-z]))((?=.*[A-Z]))((?=.*[^a-zA-Z0-9]))|
(?1) (?2) (?3) |
(?1) (?2) (?4) |
(?1) (?3) (?4) |
(?2) (?3) (?4)
).{4,8}$
One-lined:
^(?:((?=.*\d))((?=.*[a-z]))((?=.*[A-Z]))((?=.*[^a-zA-Z0-9]))|(?1)(?2)(?3)|(?1)(?2)(?4)|(?1)(?3)(?4)|(?2)(?3)(?4)).{4,8}$
Demo on Debuggex
JavaScript regex flavor does not support recursion (it does not support many things actually). Better use 4 different regexes instead, for example:
var validate = function(input) {
var regexes = [
"[A-Z]",
"[a-z]",
"[0-9]",
"[^a-zA-Z0-9]"
];
var count = 0;
for (var i = 0, n = regexes.length; i < n; i++) {
if (input.match(regexes[i])) {
count++;
}
}
return count >=3 && input.match("^.{4,8}$");
};
Sure, here's a method which uses a slight modification of the same regex, but with a short bit of code authoring required.
^(?=(\D*\d)|)(?=([^a-z]*[a-z])|)(?=([^A-Z]*[A-Z])|)(?=([a-zA-Z0-9]*[^a-zA-Z0-9])|).{4,8}$
Here you have five capturing groups - Check whether at least 3 of them are not null. A null group for capture effectively indicates that the alternative within the lookahead has been matched, and the capturing group on the left hand side could not be matched.
For example, in PHP:
preg_match("/^(?=(\\D*\\d)|)(?=([^a-z]*[a-z])|)(?=([^A-Z]*[A-Z])|)(?=([a-zA-Z0-9]*[^a-zA-Z0-9])|).{4,8}$/", $str, $matches);
$count = -1; // Because the zero-eth element is never null.
foreach ($matches as $element) {
if ( !empty($element)) {
$count += 1;
}
}
if ($count >= 3) {
// ...
}
Or Java:
Matcher matcher = Pattern.compile(...).matcher(string);
int count = 0;
if (matcher.matches())
for (int i = 1; i < 5; i++)
if (null != matcher.group(i))
count++;
if (count >= 3)
// ...
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