Budiawan
Budiawan

Reputation: 281

Password REGEX with min 6 chars, at least one letter and one number and may contain special characters

I need a regular expression with condition:

Currently I have pattern: (?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{6,50})$

However it doesn't allow special characters, does anybody have a good regex for that?

Thanks

Upvotes: 28

Views: 100020

Answers (10)

LocalPCGuy
LocalPCGuy

Reputation: 6116

First, we should make the assumption that passwords are always hashed (right? always hashed, right?). That means we should not specify the exact characters allowed (as per the 4th bullet). Rather, any characters should be accepted, and then validate on minimum length and complexity (must contain a letter and a number, for example). And since it will definitely be hashed, we have no concerns over a max length, and should be able to eliminate that as a requirement.

I agree that often this won't be done as a single regex but rather a series of small regex to validate against because we may want to indicate to the user what they need to update, rather than just rejecting outright as an invalid password. Here's some options:

As discussed above - 1 number, 1 letter (upper or lower case) and min 8 char. Added a second option that disallows leading/trailing spaces (avoid potential issues with pasting with extra white space, for example).

^(?=.*\d)(?=.*[a-zA-Z]).{8,}$
^(?=.*\d)(?=.*[a-zA-Z])\S.{6,}\S$

Lastly, if you want to require 1 number and both 1 uppercase and 1 lowercase letter, something like this would work (with or without allowing leading/trailing spaces)

^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}$
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])\S.{6,}\S$

Lastly as requested in the original post (again, don't do this, please try and push back on the requirements!!) - 1 number, 1 letter (upper or lower case), 1 special char (in list) and min 8 char, max 50 char. Both with/without allowing leading/trailing spaces, note the min/max change to account for the 2 non-whitespace characters specified.

^(?=.*\d)(?=.*[a-zA-Z])(?=.*[!@#$%^&*()_+]).{8,50}$
^(?=.*\d)(?=.*[a-zA-Z])(?=.*[!@#$%^&*()_+])\S.{6,48}\S$

Bonus - separated out is pretty simple, just test against each of the following and show the appropriate error in turn:

/^.{8,}$/       // at least 8 char; ( /^.{8,50}$/ if you must add a max)
/[A-Za-z]/      // one letter 
/[A-Z]/         // (optional) - one uppercase letter
/[a-z]/         // (optional) - one lowercase letter
/\d/            // one number
/^\S+.*\S+$/    // (optional) first and last character are non-whitespace)

Note, in these regexes, the char set for a letter is the standard English 26 character alphabet without any accented characters. But my hope is this has enough variations so folks can adapt from here as needed.

Upvotes: 0

Sverrisson
Sverrisson

Reputation: 18157

International UTF-8

None of the solutions here allow international letters, i.e. éÉöÖæÆóÓúÚáÁ, but are mainly focused on the english alphabet.

The following regEx uses unicode, UTF-8, to recognise upper and lower case and thus, allow international characters:

// Match uppercase, lowercase, digit or #$!%*?& and make sure the length is 6 to 50 in length  
const pwdFilter = /^(?=.*\p{Ll})(?=.*\p{Lu})(?=.*[\d|@#$!%*?&])[\p{L}\d@#$!%*?&]{6,50}$/gmu

if (!pwdFilter.test(pwd)) {
    // Show error that password has to be adjusted to match criteria
}

This regEx

/^(?=.*\p{Ll})(?=.*\p{Lu})(?=.*[\d|@#$!%*?&])[\p{L}\d@#$!%*?&]{6,50}$/gmu

checks if an uppercase, lowercase, digit or #$!%*?& are used in the password. It also limits the length to be 6 minimum and maximum 50 (note that the length of 😀🇺🇸🇪🇸🧑‍💻 emojis counts as more than one character in the length). The u in the end, tells it to use UTF-8.

Upvotes: 1

Tauhidurnirob
Tauhidurnirob

Reputation: 39

// more secure regex password must be :
// more than 8 chars  
// at least one number
// at least one special character
const PASSWORD_REGEX_3 = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*]).{8,}$/;

Upvotes: -1

Albz
Albz

Reputation: 2030

A more elegant and self-contained regex to match these (common) password requirements is:

^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d^a-zA-Z0-9].{5,50}$

The elegant touch here is that you don't have to hard-code symbols such as $ @ # etc.

To accept all the symbols, you are simply saying: "accept also all the not alphanumeric characters and not numbers".

Min and Max number of characters requirement

The final part of the regex {5,50} is the min and max number of characters, if the password is less than 6 or more than 50 characters entered the regex returns a non match.

Upvotes: 4

Surya R Praveen
Surya R Praveen

Reputation: 3745

DEMO https://jsfiddle.net/ssuryar/bjuhkt09/

Onkeypress the function triggerred.

HTML

<form>
<input type="text" name="testpwd" id="testpwd" class="form=control" onkeyup="checksPassword(this.value)"/>
<input type="submit" value="Submit" /><br />
<span class="error_message spassword_error" style="display: none;">Enter minimum 8 chars with atleast 1 number, lower, upper &amp; special(@#$%&!-_&amp;) char.</span>
</form>

Script

function checksPassword(password){
var pattern = /^.*(?=.{8,20})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%&!-_]).*$/;
if(!pattern.test(password)) {
$(".spassword_error").show();
}else
{
$(".spassword_error").hide();
}
}

Upvotes: 0

chii
chii

Reputation: 2209

I use this

export const validatePassword = password => {
  const re = /^(?=.*[A-Za-z])(?=.*\d)[a-zA-Z0-9!@#$%^&*()~¥=_+}{":;'?/>.<,`\-\|\[\]]{6,50}$/
  return re.test(password)
}

Upvotes: 1

Joomler
Joomler

Reputation: 2798

  1. Check a password between 7 to 16 characters which contain only characters, numeric digits, underscore and first character must be a letter-

    /^[A-Za-z]\w{7,14}$/

  2. Check a password between 6 to 20 characters which contain at least one numeric digit, one uppercase, and one lowercase letter

    /^(?=.\d)(?=.[a-z])(?=.*[A-Z]).{6,20}$/

  3. Check a password between 7 to 15 characters which contain at least one numeric digit and a special character

    /^(?=.[0-9])(?=.[!@#$%^&])[a-zA-Z0-9!@#$%^&]{7,15}$/

  4. Check a password between 8 to 15 characters which contain at least one lowercase letter, one uppercase letter, one numeric digit, and one special character

    /^(?=.\d)(?=.[a-z])(?=.[A-Z])(?=.[^a-zA-Z0-9])(?!.*\s).{8,15}$/

I hope this will help someone. For more please check this article and this site regexr.com

Upvotes: 6

Hugo
Hugo

Reputation: 1672

following jfriend00 answer i wrote this fiddle to test his solution with some little changes to make it more visual:

http://jsfiddle.net/9RB49/1/

and this is the code:

checkPwd = function() {
    var str = document.getElementById('pass').value;
    if (str.length < 6) {
        alert("too_short");
        return("too_short");
    } else if (str.length > 50) {
        alert("too_long");
        return("too_long");
    } else if (str.search(/\d/) == -1) {
        alert("no_num");
        return("no_num");
    } else if (str.search(/[a-zA-Z]/) == -1) {
        alert("no_letter");
        return("no_letter");
    } else if (str.search(/[^a-zA-Z0-9\!\@\#\$\%\^\&\*\(\)\_\+\.\,\;\:]/) != -1) {
        alert("bad_char");
        return("bad_char");
    }
    alert("oukey!!");
    return("ok");
}

btw, its working like a charm! ;)

best regards and thanks to jfriend00 of course!

Upvotes: 17

Fischermaen
Fischermaen

Reputation: 12458

I have a regex, but it's a bit tricky.

^(?:(?<Numbers>[0-9]{1})|(?<Alpha>[a-zA-Z]{1})|(?<Special>[^a-zA-Z0-9]{1})){6,50}$

Let me explain it and how to check if the tested password is correct:

There are three named groups in the regex. 1) "Numbers": will match a single number in the string. 2) "Alpha": will match a single character from "a" to "z" or "A" to "Z" 3) "Special": will match a single character not being "Alpha" or "Numbers"

Those three named groups are grouped in an alternative group, and {6,50} advises regex machine to capture at least 6 of those groups mentiond above, but not more than 50.

To ensure a correct password is entered you have to check if there is a match, and after that, if the matched groups are capture as much as you desired. I'm a C# developer and don't know, how it works in javascript, but in C# you would have to check:

match.Groups["Numbers"].Captures.Count > 1

Hopefully it works the same in javascript! Good luck!

Upvotes: 1

jfriend00
jfriend00

Reputation: 707238

Perhaps a single regex could be used, but that makes it hard to give the user feedback for which rule they aren't following. A more traditional approach like this gives you feedback that you can use in the UI to tell the user what pwd rule is not being met:

function checkPwd(str) {
    if (str.length < 6) {
        return("too_short");
    } else if (str.length > 50) {
        return("too_long");
    } else if (str.search(/\d/) == -1) {
        return("no_num");
    } else if (str.search(/[a-zA-Z]/) == -1) {
        return("no_letter");
    } else if (str.search(/[^a-zA-Z0-9\!\@\#\$\%\^\&\*\(\)\_\+]/) != -1) {
        return("bad_char");
    }
    return("ok");
}

Upvotes: 73

Related Questions