106

I want a regular expression to check that

a password must be eight characters including one uppercase letter, one special character and alphanumeric characters.

And here is my validation expression which is for eight characters including one uppercase letter, one lowercase letter, and one number or special character.

(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$"

How I can write it for a password that must be eight characters including one uppercase letter, one special character and alphanumeric characters?

Stevoisiak
  • 16,510
  • 19
  • 94
  • 173
Rania Umair
  • 1,735
  • 3
  • 16
  • 17
  • 28
    Why do you need a regular expression for this? A complete regular expression matching your requirements will be very long and complex. It's easier to write your constraints in C# code. – Greg Hewgill Feb 28 '12 at 07:24
  • Dear sir it is users requirement and i have to do it. – Rania Umair Feb 28 '12 at 07:25
  • http://regexlib.com/REDetails.aspx?regexp_id=213 has a simple using alphanumeric chars – dankyy1 Feb 28 '12 at 07:28
  • Its everything there in your regex, just delete some unneeded stuff. But what do you mean with "Alphanumeric Characters"? You already require an uppercase letter, so at least one alphanumeric is there. – stema Feb 28 '12 at 07:34
  • 34
    Have you considered checking for a strong password, rather than checking that the password meets some arbitrary rules which are an imperfect proxy for a strong password? There are plenty of libraries and programs which, when fed a password, will determine its strength. – Wayne Conrad Feb 28 '12 at 07:45
  • dear @stema i want 1 special character must in my regex – Rania Umair Feb 28 '12 at 07:46
  • 4
    @GregHewgill I would upvote your comment if I could :-) This looks like another case of "if all you have is a hammer, everything starts to look like a nail". – Christian.K Feb 28 '12 at 07:54
  • 3
    Do you need **exactly** one uppercase/special character or **at least** one? – mmdemirbas Feb 28 '12 at 08:16
  • 4
    By user's requirement, do you mean your user is dictating implementation detail? Perhaps they should just code this themselves, then. To be honest, I think it would be easier to maintain and understand if you just created counters and checked every character one by one, incrementing the appropriate counters for every character that matches a rule. From a technical standpoint it's not something that will impress anyone, but why complicate things with something that will be error-prone and hard to update? –  Jul 28 '14 at 19:54
  • 2
    Please don't subject your users to such an arbitrary password requirement, you'll royally piss off all your power users. – Nick Sweeting Nov 17 '15 at 22:50
  • 1
    It is also worth noting that [any password of 8 characters or less is perilously close to no password at all.](https://blog.codinghorror.com/password-rules-are-bullshit/) – nateirvin Mar 13 '18 at 19:32
  • 2
    The password complexity requirement looks a bit outdated. The need for at least 1 special character was orginally imposed by NIST and copied by many organizations. About a year ago, NIST dropped the requirement for a special character in its NIST.SP.800-63 version of the standard. (Free download at https://pages.nist.gov/800-63-3/ ) , acknowledging that this makes passwords much harder to remember and don't add safety. Maybe worth checking if your organizations would want to the lead in adopting? – OldFrank Jul 11 '18 at 10:26

13 Answers13

135

The regular expression you are after will most likely be huge and a nightmare to maintain especially for people who are not that familiar with regular expressions.

I think it would be easier to break your regex down and do it one bit at a time. It might take a bit more to do, but I am pretty sure that maintaining it and debugging it would be easier. This would also allow you to provide more directed error messages to your users (other than just Invalid Password) which should improve user experience.

From what I am seeing you are pretty fluent in regex, so I would presume that giving you the regular expressions to do what you need would be futile.

Seeing your comment, this is how I would go about it:

  • Must be eight characters Long: You do not need a regex for this. Using the .Length property should be enough.

  • Including one uppercase letter: You can use the [A-Z]+ regular expression. If the string contains at least one upper case letter, this regular expression will yield true.

  • One special character: You can use either the \W which will match any character which is not a letter or a number or else, you can use something like so [!@#] to specify a custom list of special characters. Note though that characters such as $, ^, ( and ) are special characters in the regular expression language, so they need to be escaped like so: \$. So in short, you might use the \W.

  • Alphanumeric characters: Using the \w+ should match any letter and number and underscore.

Take a look at this tutorial for more information.

npinti
  • 50,175
  • 5
  • 67
  • 92
  • 2
    i have not written this my self i get it from google dear friend – Rania Umair Feb 28 '12 at 07:41
  • 4
    @RaniaUmair: I think that your comment proves my point. I would recommend that you break it down like I have specified. – npinti Feb 28 '12 at 07:50
  • 39
    +1 Regex is powerful, but wasn't meant to solve any problem in the universe – Cristian Lupascu Feb 28 '12 at 07:51
  • @w0lf: I could not agree more. Regex is powerful, however, it gets too complex too fast, so better keep it simple. – npinti Feb 28 '12 at 07:57
  • can you help me i need a regx which accept at least one number and maximum 3 other charecters can be anything – Lijo Jul 06 '14 at 19:55
  • @Lijo: To match the 1 number, use the `\d`. That will yield `true` if there is at least one digit in the string. For the rest, use the `.length` property for strings. – npinti Jul 07 '14 at 04:17
  • 2
    Too late for a response; but this method also allows to tell the user exactly where they went wrong.. Where a regex containing it all will only be able to say what the requirements are.. Breaking it down into multiple "if's" will let you tell the user: "Oooh wait, you need to have at least one symbol" and such.. Way more user friendly. – Lasse R Sep 23 '15 at 08:50
  • @LasseRafn: Thanks for the input, I've updated the answer. – npinti Sep 23 '15 at 09:22
  • 1
    Wouldn't it be sufficient to check `[A-Z]` (without the `+`) here? Since you're just checking that at least one exists in the password, you only need to match one (not however many in a row there are). – jpmc26 Dec 08 '15 at 18:56
  • I think the answer should be a combination of the OPs request and this answer. I agree that a single regex would not be a user friendly (or a good algorithm or code readable) solution, but a regex for each requirement, coupled with an error message would. So I propose you describe your password requirements as a list of regex, error message pairs which describe each requirement and return the message if not passed. – Siderite Zackwehdex Apr 30 '19 at 18:44
  • The answer doesn't address the issue of how to check for AND-conditions with the regular expression itself, which is where the difficulty and confusion comes from. Yes, you can write non-regex code to check for everything required or use multiple expressions, but that wasn't the question. – relatively_random Sep 26 '19 at 08:20
108
(                   # Start of group
    (?=.*\d)        #   must contain at least one digit
    (?=.*[A-Z])     #   must contain at least one uppercase character
    (?=.*\W)        #   must contain at least one special symbol
       .            #     match anything with previous condition checking
         {8,8}      #        length is exactly 8 characters
)                   # End of group

In one line:

((?=.*\d)(?=.*[A-Z])(?=.*\W).{8,8})

Edit 2019-05-28:

You need to match entire input string. So, you can enclose the regex between ^ and $ to prevent accidentally assuming partial matches as matching entire input:

^((?=.*\d)(?=.*[A-Z])(?=.*\W).{8,8})$

Sources:

mmdemirbas
  • 8,486
  • 5
  • 44
  • 51
34

So many answers.... all bad!

Regular expressions don't have an AND operator, so it's pretty hard to write a regex that matches valid passwords, when validity is defined by something AND something else AND something else...

But, regular expressions do have an OR operator, so just apply DeMorgan's theorem, and write a regex that matches invalid passwords.

anything with less than 8 characters OR anything with no numbers OR anything with no uppercase OR anything with no special characters

So:

^(.{0,7}|[^0-9]*|[^A-Z]*|[a-zA-Z0-9]*)$

If anything matches that, then it's an invalid password.

Matt Timmermans
  • 36,921
  • 2
  • 27
  • 59
13

The answer is to not use a regular expression. This is sets and counting.

Regular expressions are about order.

In your life as a programmer you will asked to do many things that do not make sense. Learn to dig a level deeper. Learn when the question is wrong.

The question (if it mentioned regular expressions) is wrong.

Pseudocode (been switching between too many languages, of late):

if s.length < 8:
    return False
nUpper = nLower = nAlphanum = nSpecial = 0
for c in s:
    if isUpper(c):
        nUpper++
    if isLower(c):
        nLower++
    if isAlphanumeric(c):
        nAlphanum++
    if isSpecial(c):
        nSpecial++
return (0 < nUpper) and (0 < nAlphanum) and (0 < nSpecial)

Bet you read and understood the above code almost instantly. Bet you took much longer with the regex, and are less certain it is correct. Extending the regex is risky. Extended the immediate above, much less so.

Note also the question is imprecisely phrased. Is the character set ASCII or Unicode, or ?? My guess from reading the question is that at least one lowercase character is assumed. So I think the assumed last rule should be:

return (0 < nUpper) and (0 < nLower) and (0 < nAlphanum) and (0 < nSpecial)

(Changing hats to security-focused, this is a really annoying/not useful rule.)

Learning to know when the question is wrong is massively more important than clever answers. A clever answer to the wrong question is almost always wrong.

  • 2
    I agree. The more people you work with, the more code needs to be readable although some regexp implementation I saw as answers are quite clear – Nicola Peluchetti Sep 24 '15 at 00:34
  • I like that some users like you have courage to say that Regex is not always better solution to apply and that sometime, simple programming is more readable. – schlebe Jun 11 '20 at 07:05
12

As an example how this could be done with a readable/maintainable regex.

For a longer regex you should always use RegexOptions.IgnorePatternWhitespace to allow whitespace and comments in the expression for better readability.

String[] passwords = { "foobar", "Foobar", "Foobar1", "Fooobar12" };

foreach (String s in passwords) {

    Match password = Regex.Match(s, @"
                                      ^              # Match the start of the string
                                       (?=.*\p{Lu})  # Positive lookahead assertion, is true when there is an uppercase letter
                                       (?=.*\P{L})   # Positive lookahead assertion, is true when there is a non-letter
                                       \S{8,}        # At least 8 non whitespace characters
                                      $              # Match the end of the string
                                     ", RegexOptions.IgnorePatternWhitespace);

    if (password.Success) {
        Console.WriteLine(s + ": valid");
    }
    else {
        Console.WriteLine(s + ": invalid");
    }
}

Console.ReadLine();
stema
  • 80,307
  • 18
  • 92
  • 121
  • This is the best way to abuse the `lookahead assertion` as kind of an "and" pattern to cover the whole constraint within a single regex. Works for more constraints and can easily be generated if some constraints should be enabled/disabled by configuration. – dognose Sep 22 '15 at 15:40
  • 2
    The use of [Unicode categories](http://www.regular-expressions.info/unicode.html) is an excellent idea. The world is wider than ASCII! – Walter Tross Nov 17 '15 at 22:36
1

The regular expression you was looking for is: /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*\[\]"\';:_\-<>\., =\+\/\\]).{8,}$/u.

Example and test: http://regexr.com/3fhr4

Lucas Silva
  • 1,105
  • 9
  • 17
1

If you need only one upper case and special character then this should work:

@"^(?=.{8,}$)(?=[^A-Z]*[A-Z][^A-Z]*$)\w*\W\w*$"
user1096188
  • 1,779
  • 10
  • 11
0

This question starts to be viral and a lot of interesting suggestion appeared.

Yes, writing by hand is difficult. So an easier solution is to use a template. Although the resulted regex may not be most optimal, it will be easier to maintain and/or change, and the user will have a better control over the result. It is possible that I missed something, so any constructive criticism will be helpful.

This links might be interesting: match at least 2 digits 2 letters in any order in a string, Regular Expression Language, Capturing groups

I'm using this template (?=(?:.*?({type})){({count})}) based on all of the regex I saw in SO. The next step is replacing the needed pattern ( number, special character ... ) and adding configuration for length.

I've made a little class for composing the regex PasswordRegexGenerator.cs An example:

string result = new PasswordRegexGenerator ( )
        .UpperCase ( 3, -1 )    // ... {3,}
        .Number ( 2, 4 )        // ... {2,4}
        .SpecialCharacter ( 2 ) // ... {2}
        .Total ( 8,-1 )
        .Compose ( );

/// <summary>
/// Generator for regular expression, validating password requirements.
/// </summary>
public class PasswordRegexGenerator
{
    private string _elementTemplate = "(?=(?:.*?({type})){({count})})";

    private Dictionary<string, string> _elements = new Dictionary<string, string> {
        { "uppercase", "[A-Z]" },
        { "lowercase", "[a-z]" },
        { "number", @"\d" },
        { "special", @"\W" },
        { "alphanumeric", @"\w" }
    };

    private StringBuilder _sb = new StringBuilder ( );

    private string Construct ( string what, int min, int max )
    {
        StringBuilder sb = new StringBuilder ( _elementTemplate );
        string count = min.ToString ( );

        if ( max == -1 )
        {
            count += ",";
        }
        else if ( max > 0 )
        {
            count += "," + max.ToString();
        }

        return sb
            .Replace ( "({type})", what )
            .Replace ( "({count})", count )
            .ToString ( );
    }

    /// <summary>
    /// Change the template for the generation of the regex parts
    /// </summary>
    /// <param name="newTemplate">the new template</param>
    /// <returns></returns>
    public PasswordRegexGenerator ChangeRegexTemplate ( string newTemplate )
    {
        _elementTemplate = newTemplate;
        return this;
       }

    /// <summary>
    /// Change or update the regex for a certain type ( number, uppercase ... )
    /// </summary>
    /// <param name="name">type of the regex</param>
    /// <param name="regex">new value for the regex</param>
    /// <returns></returns>
    public PasswordRegexGenerator ChangeRegexElements ( string name, string regex )
    {
        if ( _elements.ContainsKey ( name ) )
        {
            _elements[ name ] = regex;
        }
        else
        {
            _elements.Add ( name, regex );
        }
        return this;
    }

    #region construction methods 

    /// <summary>
    /// Adding number requirement
    /// </summary>
    /// <param name="min"></param>
    /// <param name="max"></param>
    /// <returns></returns>
    public PasswordRegexGenerator Number ( int min = 1, int max = 0 )
    {
        _sb.Append ( Construct ( _elements[ "number" ], min, max ) );
        return this;
    }

    public PasswordRegexGenerator UpperCase ( int min = 1, int max = 0 )
    {
        _sb.Append ( Construct ( _elements[ "uppercase" ], min, max ) );
        return this;
    }

    public PasswordRegexGenerator LowerCase ( int min = 1, int max = 0 )
    {
        _sb.Append ( Construct ( _elements[ "lowercase" ], min, max ) );
        return this;
    }

    public PasswordRegexGenerator SpecialCharacter ( int min = 1, int max = 0 )
    {
        _sb.Append ( Construct ( _elements[ "special" ], min, max ) );
        return this;
    }

    public PasswordRegexGenerator Total ( int min, int max = 0 )
    {
        string count = min.ToString ( ) + ( ( max == 0 ) ? "" : "," + max.ToString ( ) );
        _sb.Append ( ".{" + count + "}" );
        return this;
    }

    #endregion

    public string Compose ()
    {
        return "(" + _sb.ToString ( ) + ")";
    }
}
Community
  • 1
  • 1
Bakudan
  • 17,636
  • 9
  • 48
  • 69
0

You can use below class for validation:

public class PasswordValidator{

  private Pattern pattern;
  private Matcher matcher;

  private static final String PASSWORD_PATTERN =
          "((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{6,20})";

  public PasswordValidator(){
      pattern = Pattern.compile(PASSWORD_PATTERN);
  }

  /**
   * Validate password with regular expression
   * @param password password for validation
   * @return true valid password, false invalid password
   */
  public boolean validate(final String password){

      matcher = pattern.matcher(password);
      return matcher.matches();

  }
}

where 6 and 20 are minimum and maximum length for the password.

amit pandya
  • 1,174
  • 11
  • 20
0
  • Use a nonbacktracking expression to match the whole password first, if it has at least 8 characters (this way, there is no combinatorial explosion for long, but invalid passwords): (?>{8,})
  • Use lookbehind assertions to check for presence of all required characters (AND-conditions). (?<=...)
  • At least one uppercase character: (?<=\p{Lu}.*)
  • At least one special character (a bit ambiguous, but let's use not-word): (?<=\W.*)
  • At least one alphanumeric character (: (?<=\w.*)

Summed up:

(?>.{8,})(?<=\p{Lu}.*)(?<=\W.*)(?<=\w.*)

relatively_random
  • 3,232
  • 1
  • 18
  • 38
0

Best is not using regex for everything. Those requirements are very light. On CPU-wise string operations for checking the criteria/validation is much cheaper and faster than regex!

ANSerpen
  • 313
  • 3
  • 9
0

var regex =/^(?=.*\d)(?=.*[!@#$%^&*])(?=.*[a-z])(?=.*[A-Z]).{8,64}$/;

 
function test() {

 if(regex.test(document.getElementById("txtPassword").value)===false)
 {
 alert("Min 6,Max 64,At Least One Uppercase Character,One Lowercase Character,One Numeric Value And One Special Character(!@#$%^&*) Required ");
 }
 else
 {
 alert("Success");
 }
}
<input type="text" id="txtPassword" />
<button id="testBtn" onclick=test()>CheckPassword</button>
Brian Tompsett - 汤莱恩
  • 5,195
  • 62
  • 50
  • 120
  • While this code snippet may solve the problem, it doesn't explain why or how it answers the question. Please [include an explanation for your code](https://meta.stackexchange.com/q/114762/269535), as that really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. You can use the [edit] button to improve this answer to get more votes and reputation! – Brian Tompsett - 汤莱恩 Sep 06 '20 at 10:15
-2
/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}$/
Nikolay Kostov
  • 14,580
  • 20
  • 75
  • 115
Kailash Karki
  • 1,600
  • 1
  • 9
  • 6
  • 15
    I suggest you edit your question and include some explanation. Code-only answers are sometimes good enough, but code + explanation answers are always better – Barranka Jan 21 '15 at 14:52