19

Edit: Thanks for the advice to make my question clearer :)

The Match is looking for 3 consecutive characters:

Regex Match =AaA653219
Regex Match = AA5556219

The code is ASP.NET 4.0. Here is the whole function:

public ValidationResult ApplyValidationRules()
{
    ValidationResult result = new ValidationResult();
    Regex regEx = new Regex(@"^(?=.*\d)(?=.*[a-zA-Z]).{8,20}$");

    bool valid = regEx.IsMatch(_Password);
    if (!valid)
        result.Errors.Add("Passwords must be 8-20 characters in length, contain at least one alpha character and one numeric character");

    return result;
}

I've tried for over 3 hours to make this work, referencing the below with no luck =/

How can I find repeated characters with a regex in Java?

.net Regex for more than 2 consecutive letters

I have started with this for 8-20 characters a-Z 0-9 :

^(?=.*\d)(?=.*[a-zA-Z]).{8,20}$
As Regex regEx = new Regex(@"^(?=.*\d)(?=.*[a-zA-Z]).{8,20}$");

I've tried adding variations of the below with no luck:

/(.)\1{9,}/
.*([0-9A-Za-z])\\1+.*
((\\w)\\2+)+". 

Any help would be much appreciated!

CarenRose
  • 1,266
  • 1
  • 12
  • 24
TacRedline
  • 193
  • 1
  • 1
  • 5

2 Answers2

42

http://regexr.com?34vo9

The regular expression:

^(?=.{8,20}$)(([a-z0-9])\2?(?!\2))+$

The first lookahead ((?=.{8,20}$)) checks the length of your string. The second portion does your double character and validity checking by:

(
  ([a-z0-9])      Matching a character and storing it in a back reference.
  \2?             Optionally match one more EXACT COPY of that character.
  (?!\2)          Make sure the upcoming character is NOT the same character.
)+                Do this ad nauseum.
$                 End of string.

Okay. I see you've added some additional requirements. My basic forumla still works, but we have to give you more of a step by step approach. SO:

^...$

Your whole regular expression will be dropped into start and end characters, for obvious reasons.

(?=.{n,m}$)

Length checking. Put this at the beginning of your regular expression with n as your minimum length and m as your maximum length.

(?=(?:[^REQ]*[REQ]){n,m})

Required characters. Place this at the beginning of your regular expression with REQ as your required character to require N to M of your character. YOu may drop the (?: ..){n,m} to require just one of that character.

(?:([VALID])\1?(?!\1))+

The rest of your expression. Replace VALID with your valid Characters. So, your Password Regex is:

^(?=.{8,20}$)(?=[^A-Za-z]*[A-Za-z])(?=[^0-9]*[0-9])(?:([\w\d*?!:;])\1?(?!\1))+$

'Splained:

^
  (?=.{8,20}$)                 8 to 20 characters
  (?=[^A-Za-z]*[A-Za-z])       At least one Alpha
  (?=[^0-9]*[0-9])             At least one Numeric
  (?:([\w\d*?!:;])\1?(?!\1))+  Valid Characters, not repeated thrice.
$

http://regexr.com?34vol Here's the new one in action.

FrankieTheKneeMan
  • 6,645
  • 2
  • 26
  • 37
  • @TacRedline You're Welcome. I've added instructions for a bake your own validator RegEx that should allow you to do all your extra stuff. This stuff gets pretty unreadable pretty fast though - you may want to compile it in parts for better self documentation, or provide a lot of Comments. Feel free to mark this answer as "accepted" if it answered your question. – FrankieTheKneeMan May 23 '13 at 15:48
  • 1
    @FrankieTheKneeMan I tried to use regex with predicate for consecutive character but when there is two repetitive character I am getting "True" but in case of three or more than two consecutive character I am getting false. here is my code, let consecutiveRegEx = "(?:([\\w\\d*?!:;])\\1?(?!\\1))+$" let pred = NSPredicate(format: "SELF MATCHES %@ ", consecutiveRegEx) debugPrint(" isConNumber - \(pred.evaluate(with: password))") – Soumen May 23 '18 at 06:55
1

Tightened up matching criteria as it was too broad; for example, "not A-Za-z" matches a lot more than is intended. The previous REGEX was matching on the string "ThiIsNot". For the most part, passwords are only going to contain alphanumeric and punctation characters, so I limited the scope, which made all matches more accurate. Used character classes for human readability. Added and exclusion list, and differentiated upper and lower case letters.

^(?=.{8,20}$)(?!(?:.*[01IiLlOo]))(?=(?:[\[[:digit:]\]\[[:punct:]\]]*[\[[:alpha:]\]]){2})(?=(?:[\[[:digit:]\]\[[:punct:]\]\[[:upper:]\]]*[\[[:lower:]\]]){1})(?=(?:[\[[:digit:]\]\[[:punct:]\]\[[:lower:]\]]*[\[[:upper:]\]]){1})(?=(?:[\[[:alpha:]\]\[[:punct:]\]]*[\[[:digit:]\]]){1})(?=(?:[\[[:alnum:]\]]*[\[[:punct:]\]]){1})(?:([\[[:alnum:]\]\[[:punct:]\]])\1?(?!\1))+$

The breakdown:

^(?=.{8,20}$) - Positive lookahead that the string is between 8 and 20 chars
(?!(?:.*[01IiLlOo])) - Negative lookahead for any blacklisted chars
(?=(?:[\[[:digit:]\]\[[:punct:]\]]*[\[[:alpha:]\]]){2}) - Verify that at least 2 alpha chars exist
(?=(?:[\[[:digit:]\]\[[:punct:]\]\[[:upper:]\]]*[\[[:lower:]\]]){1}) - Verify that at least 1 lowercase alpha exists
(?=(?:[\[[:digit:]\]\[[:punct:]\]\[[:lower:]\]]*[\[[:upper:]\]]){1}) - Verify that at least 1 uppercase alpha exists
(?=(?:[\[[:alpha:]\]\[[:punct:]\]]*[\[[:digit:]\]]){1}) - Verify that at least 1 digit exists
(?=(?:[\[[:alnum:]\]]*[\[[:punct:]\]]){1}) - Verify that at least 1 special/punctuation char exists
(?:([\[[:alnum:]\]\[[:punct:]\]])\1?(?!\1))+$ - Verify that no char is repeated more than twice in a row
Sebo
  • 11
  • 2