Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex for checking that at least 3 of 4 different character groups exist

I'm trying to write a password validator.

How can I see if my supplied string contains at least 3 different character groups?

It's easy enough to check if they are existant or not ---but at least 3?

  • at least eight (8) characters

  • At least three different character groups

    upper-case letter

    lower-case letter

    numeric

    special characters !@#$%&/=?_.,:;-\

(I'm using javascript for regex)

like image 932
Yonder Avatar asked May 10 '11 13:05

Yonder


People also ask

How do you find multiple occurrences of a string in regex?

Method 1: Regex re. To get all occurrences of a pattern in a given string, you can use the regular expression method re. finditer(pattern, string) . The result is an iterable of match objects—you can retrieve the indices of the match using the match. start() and match.

What does \f mean in regex?

Definition and Usage The \f metacharacter matches form feed characters.

What is Slash's regex?

The backslash in combination with a literal character can create a regex token with a special meaning. E.g. \d is a shorthand that matches a single digit from 0 to 9. Escaping a single metacharacter with a backslash works in all regular expression flavors.

How do I check a pattern in regex?

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).


2 Answers

Just to learn - would this kind of requirement be possible to implement in pure regex?

That'd make it a rather hard to read (and therefor maintain!) solution, but here it is:

(?mx)
^
(
  (?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])                # must contain a-z, A-Z and 0-9
  |                                                # OR
  (?=.*[a-z])(?=.*[A-Z])(?=.*[!@\#$%&/=?_.,:;\\-]) # must contain a-z, A-Z and special
  |                                                # OR
  (?=.*[a-z])(?=.*[0-9])(?=.*[!@\#$%&/=?_.,:;\\-]) # must contain a-z, 0-9 and special
  |                                                # OR
  (?=.*[A-Z])(?=.*[0-9])(?=.*[!@\#$%&/=?_.,:;\\-]) # must contain A-Z, 0-9 and special
)
.{8,}                                              # at least 8 chars
$

A (horrible) Javascript demo:

var pw = "aa$aa1aa";
if(pw.match(/^((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])|(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%&\/=?_.,:;\\-])|(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%&\/=?_.,:;\\-])|(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%&\/=?_.,:;\\-])).{8,}$/)) {
  print('Okay!');
} else {
  print('Fail...');
}

prints: Okay!, as you can see on Ideone.

like image 54
Bart Kiers Avatar answered Nov 08 '22 18:11

Bart Kiers


May as well join in on the fun:

String.prototype.isValidPW = function(){   
    // First, check for at least 8 characters
    if (this.length < 8) return false;

    // next, check that we have at least 3 matches
    var re = [/\d/, /[A-Z]/, /[a-z]/, /[!@#$%&\/=?_.,:;-]/], m = 0;
    for (var r = 0; r < re.length; r++){
        if ((this.match(re[r]) || []).length > 0) m++;
    }

    return m >= 3;
};

if ("P@ssW0rd".isValidPW()) alert('Acceptable!');

Demo

like image 31
Brad Christie Avatar answered Nov 08 '22 18:11

Brad Christie