0

I am trying to find a regex which will give me the following validation:

string should contain at least 1 digit and at least 1 special character. Does allow alphanumeric.

I tried the following but this fails:

@"^[a-zA-Z0-9@#$%&*+\-_(),+':;?.,!\[\]\s\\/]+$]"

I tried "password1$" but that failed I also tried "Password1!" but that also failed.

ideas?

UPDATE Need the solution to work with C# - currently the suggestions posted as of Oct 22 2013 do not appear to work.

Ahmed ilyas
  • 5,722
  • 8
  • 44
  • 72
  • 1
    Side note: forcing people to have special characters in passwords simply makes passwords harder to remember and forces using of simpler passwords as result. And makes people less happy with your application... – Alexei Levenkov Oct 22 '13 at 06:24
  • possible duplicate of [Regex for alpanumeric with at least 1 number and 1 character](http://stackoverflow.com/questions/7684815/regex-for-alpanumeric-with-at-least-1-number-and-1-character) – Toto Oct 22 '13 at 07:22
  • @Alexei - yes I know but that is not up to me. – Ahmed ilyas Oct 22 '13 at 13:16
  • @M42 - no, this is not a possible duplicate. Completely different requirement and question – Ahmed ilyas Oct 22 '13 at 13:17
  • possible duplicate of [Regular Expression for password validation](http://stackoverflow.com/questions/5859632/regular-expression-for-password-validation) – Nicholas Carey Oct 23 '13 at 00:36

5 Answers5

4

Try this:

Regex rxPassword = new Regex( @"
  ^               # start-of-line, followed by
  [a-zA-Z0-9!@#]+ # a sequence of one or more characters drawn from the set consisting of ASCII letters, digits or the punctuation characters ! @ and #
  (<=[0-9])       # at least one of which is a decimal digit
  (<=[!@#])       # at least one of which is one of the special characters
  (<=[a-zA-Z])    # at least one of which is an upper- or lower-case letter
  $               # followed by end-of-line
" , RegexOptions.IgnorePatternWhitespace ) ;

The construct (<=regular-expression) is a zero-width positive look-behind assertion.

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
1

Sometimes it's a lot simpler to do things one step at a time. The static constructor builds the escaped character class characters from a simple list of allowed special characters. The built-in Regex.Escape method doesn't work here.

public static class PasswordValidator {

    private const string ALLOWED_SPECIAL_CHARS = @"@#$%&*+_()':;?.,![]\-";
    private static string ESCAPED_SPECIAL_CHARS;

    static PasswordValidator() {
        var escapedChars = new List<char>();
        foreach (char c in ALLOWED_SPECIAL_CHARS) {
            if (c == '[' || c == ']' || c == '\\' || c == '-')
                escapedChars.AddRange(new[] { '\\', c });
            else
                escapedChars.Add(c);
        }
        ESCAPED_SPECIAL_CHARS = new string(escapedChars.ToArray());
    }

    public static bool IsValidPassword(string input) {
        // Length requirement?
        if (input.Length < 8) return false;

        // First just check for a digit
        if (!Regex.IsMatch(input, @"\d")) return false;

        // Then check for special character
        if (!Regex.IsMatch(input, "[" + ESCAPED_SPECIAL_CHARS + "]")) return false;

        // Require a letter?
        if (!Regex.IsMatch(input, "[a-zA-Z]")) return false;

        // DON'T allow anything else:
        if (Regex.IsMatch(input, @"[^a-zA-Z\d" + ESCAPED_SPECIAL_CHARS + "]")) return false;

        return true;
    }
}
Joshua Honig
  • 12,925
  • 8
  • 53
  • 75
  • I completely agree with this way of doing things, especially since validating passwords usually doesn't require excellent performance, but your answer allows special characters that are out of the allowed range. For example `abcdef1234234+~~~~` would be valid but `~` isn't an accepted character. – dee-see Oct 23 '13 at 00:36
0

This should do the work

(?:(?=.*[0-9]+)(?=.*[a-zA-Z]+)(?=.*[@#$%&*+\-_(),+':;?.,!\[\]\s\\/]+))+

Tested with javascript, not sure about c#, may need some little adjust.

What it does is use anticipated positive lookahead to find the required elements of the password.

EDIT

Regular expression is designed to test if there are matches. Since all the patterns are lookahead, no real characters get captured and matches are empty, but if the expression "match", then the password is valid.

But, since the question is C# (sorry, i don't know c#, just improvising and adapting samples)

    string input = "password1!";
    string pattern = @"^(?:(?=.*[0-9]+)(?=.*[a-zA-Z]+)(?=.*[@#$%&*+\-_(),+':;?.,!\[\]\s\\/]+))+.*$";
    Regex rgx = new Regex(pattern, RegexOptions.None);

    MatchCollection matches = rgx.Matches(input);
   if (matches.Count > 0) {
      Console.WriteLine("{0} ({1} matches):", input, matches.Count);
      foreach (Match match in matches)
         Console.WriteLine("   " + match.Value);
    }

Adding start of line, and a .*$ to the end, the expression will match if the password is valid. And the match value will be the password. (i guess)

MC ND
  • 69,615
  • 8
  • 84
  • 126
  • Thanks. OK, change of requirement! must be min of 8 chars, at least one number and an optional special chars. – Ahmed ilyas Oct 23 '13 at 20:46
  • What does "an optional special chars" exactly mean? It can be present or not (optional of course), but if present only one or can it be more than one ? – MC ND Oct 24 '13 at 06:04
0

This may be work, there are two possible, the digit before special char or the digit after the special char. You should use DOTALL(the dot point all char)

^((.*?[0-9].*?[@#$%&*+\-_(),+':;?.,!\[\]\s\\/].*)|(.*?[@#$%&*+\-_(),+':;?.,!\[\]\s\\/].*?[0-9].*))$
Yhzhtk
  • 174
  • 1
  • 10
0

This worked for me:

@"(?=^[!@#$%\^&*()_-+=[{]};:<>|./?a-zA-Z\d]{8,}$)(?=([!@#$%\^&*()_-+=[{]};:<>|./?a-zA-Z\d]\W+){1,})(?=[^0-9][0-9])[!@#$%\^&*()_-+=[{]};:<>|./?a-zA-Z\d]*$"

alphanumeric, at least 1 numeric, and special character with a min length of 8

Ahmed ilyas
  • 5,722
  • 8
  • 44
  • 72