Matching any password except one containing repeating characters [duplicate] - regex

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!

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.

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

Related

Am I implementing negative lookaheads correctly with my regex?

I'm a beginner with regex and stuck with creating regex with the following conditions:
Minimum of 8 characters
Maximum of 60 characters
Must contain 2 letters
Must contain 1 number
Must contain 1 special character
Special character cannot be the following: & ` ( ) = [ ] | ; " ' < >
So far I have the following...
(?=^.{8,60}$)(?=.*\d)(?=[a-zA-Z]{2,})(?!.*[&`()=[|;"''\]'<>]).*
But my last two tests are failing and I have no idea why...
!##$%^*+-_~?,.{}!HR12345
123456789AB!
If you'd like to see my test and expected results, visit here: https://regexr.com/73m2o
My tests contains acceptable number of characters, appropriate number of alphabetic characters, and supported special characters... I don't know why it's failing!
Using .* to verify a character in the string can be very inefficient and I would suggest using negated character classes for the principle of contast.
Apart from that, there is a point in the question Must contain 1 special character that is not addressed yet in the current answers.
You can use a positive lookahead for that to assert one of the characters that you consider special.
^(?=[^\d\n]*\d)(?=[^a-zA-Z\n]*[a-zA-Z][^a-zA-Z\n]*[a-zA-Z])(?=[^!##$%^\n]*[!##$%^])[^&`()=[|;"''\]'<>\n]{8,60}$
Explanation
^ Start of string (Outside of the lookahead)
(?=[^\d\n]*\d) Assert a digit
(?=[^a-zA-Z\n]*[a-zA-Z][^a-zA-Z\n]*[a-zA-Z]) Assert 2 chars a-zA-Z
(?=[^!##$%^\n]*[!##$%^]) Assert a "special" character
[^&`()=[|;"''\]'<>\n]{8,60} Match 8-60 characters except for the ones that you don't want to match
$ End of string
See a regex demo.
Part of the issue is that you're missing the .* in (?=[a-zA-Z]{2,}). However, your implementation of "two or more" letters is not correct unless the letters must be consecutive.
You'll see that the string 1234567B89A! fails to match, even with the correction. You can fix this like so:
(?=^.{8,60}$)(?=.*\d)(?=.*[a-zA-Z].*[a-zA-Z])(?!.*[&`()=[|;"''\]'<>]).*
The part I changed is (?=.*[a-zA-Z].*[a-zA-Z]) asserting that we can match a letter, zero or more other characters, and then another letter.
https://regex101.com/r/jEsK0S/1
Also, there's currently no assertion that there must be a special character, only an assertion of which ones shouldn't match. So I'd suggest adding another lookahead with a list of valid special characters.
Since the 2+ alphabetical characters can appear anywhere in the string, you need to prepend your check for them with .* (as you have with the other character classes you're checking for); otherwise the positive lookaheads will, in this scenario, try to assert their appearance at the beginning of the string (position 0):
(?=^.{8,60}$)(?=.*\d)(?=.*[a-zA-Z]{2,})(?!.*[&`()=[|;"''\]'<>]).*

Validating an obfuscation token

I am building a secured algorithm to get rid of obfuscation attacks. The user is validated with the token which should satisfy following condition:
username in lowercase letters only and username is at least 5 digit long.
username is followed with #.
After # first two characters are important. A digit and a character always. This part contains at least a digit, a lowercase and an upperCase Letter.
In between there could be any number of digits or letters only.
In the last the digit and character should exactly match point-3's digit and character.
It should end with #.
The characters in the middle of two # should be at least 5 characters long.
The complete token consists only of two #, lowercase and uppercase letters and digits. And
I don't know about regular expression but my guide told me this task is easily achieved at validation time by regular expressions. After I looked for long on the internet and found some links which are similar and tried to combine them and got this:
^[a-z]{5,}#[a-zA-Z0-9]{2}[A-Z][0-9A-Za-z]*[a-zA-Z0-9]{2}#$
But this only matches 1 test case. I don't know how I can achieve the middle part of two hashes. I tried to explain my problem as per my english. Please help.
Below test cases should pass
userabcd#4a39A234a#
randomuser#4A39a234A#
abcduser#2Aa39232A#
abcdxyz#1q39A231q#
randzzs#1aB1a#
Below test cases should fail:
randuser#1aaa1a#
randuser#1112#
randuser#a1a1##
randuser#1aa#
u#4a39a234a#
userstre#1qqeqe123231q$
user#1239a23$a#
useabcd#4a39a234a#12
You may try:
^[a-z]{5,}#(?=[^a-z\n]*[a-z])(?=[^A-Z\n]*[A-Z])(\d[a-zA-Z])[a-zA-Z\d]*\1#$
Explanation of the above regex:
^, $ - Represents start and end of the line respectively.
[a-z]{5,} - Matches lower case user names 5 or more times.
# - Matches # literally.
(?=[^a-z]*[a-z]) - Represents a positive look-ahead asserting at least a lowercase letters.
(?=[^A-Z]*[A-Z]) - Represents a positive look-ahead asserting at least an uppercase letters.
(\d[a-zA-Z]) - Represents a capturing group matching first 2 character i.e. a digit and a letter. If you want other way then use [a-zA-Z]\d.
[a-zA-Z\d]* - Matching zero or more of the characters in mentioned character set.
\1 - Represents back-reference exactly matching the captured group.
You can find the demo of the above regex in here.
Note: If you want to match one string at a time i.e. for practical purposes; remove \n from the character sets.
You can use this regex as an alternative.
^[a-z]{5,}#(?=.*?[a-z])(?=.*?[A-Z])(\d[a-zA-Z])[a-zA-Z\d]*\1#$
Recommended reading: Principle of contrast

.net Regex to look ahead and eliminate strings in advance that dont contain certain characters

I am Using .Net Flavor of Regex.
Suppose i have a string 123456789AB
and i want to match AB (Could be any two Capital letters) only if the string part containing numbers(123456789) has 5 and 8 in it.
So what i came up with was
(?=5)(?=8)([A-Z]{2})
But this is not working.
After some trail error on RegexStorm
I got to
(?=(.*5))(?=(.*8))[A-Z]{2}
What i am expecting is it will start matching from the start of the string as look ahead does not consume any characters.
But the part "[A-Z]{2}" does not move ahead to match AB in the input string.
My question is why is that so?
i know replacing it with .*[A-Z]{2} will make it move ahead but then the string matched has entire string in it.
What is the solution in this case other than putting word part ([A-Z]{2}) in a separate group and then catching only that group.
Lookaheads check for the pattern match immediately to the right of the current position in the string. (?=(.*5))(?=(.*8)) matches a location that is immediately followed with any 0 or more chars other than line break chars as many as possible and then 5 and then - at the same position - another similar check if performed but requiring 8 after any zero or more chars, as many as possible.
You may use as many as lookbehinds as there are required substrings before the two letters:
(?s)(?<=5.*?)(?<=8.*?)[A-Z]{2}
See the regex demo
Details
(?s) - makes the . match newline characters, too
(?<=5.*?) - a location that is immediately preceded with 5 and then 0 or more chars as few as possible
(?<=8.*?) - a location that is immediately preceded with 8 and then 0 or more chars as few as possible
[A-Z]{2} - two ASCII uppercase letters.
An alternative would be to "unfold" what you expect to match using exclusionary character classes and alternation of match order. Not pretty, but pretty fast:
(?<=\b[^58]*?(?:5[^8]*8|8[^5]*5)[^A-Z]*?)[A-Z]{2}

Regex matching string containing at least x characters and x numbers

I have a requirement to test if string matches following rules:
Has at least 8 [a-zA-Z!##$%^&+=] characters and has at least 1 [0-9] number OR
Has at least 8 [0-9] numbers and has at least 1 [a-zA-Z!##$%^&+=] character
So far I tried this:
"^(?=(?=.*[a-zA-Z!##$%^&+=].*[a-zA-Z!##$%^&+=].*[a-zA-Z!##$%^&+=].*[a-zA-Z!##$%^&+=].*[a-zA-Z!##$%^&+=].*[a-zA-Z!##$%^&+=].*[a-zA-Z!##$%^&+=].*[a-zA-Z!##$%^&+=])(?=.*[0-9])|(?=.*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9])(?=.*[a-zA-Z!##$%^&+=])).{8,}\$")
It mostly works ok, but one scenario is failing:
"!abcdefgh1" --> matched (OK)
"{abcdefgh1" --> matched (NOT OK because character { shouldn't be allowed)
How to disallow any other characters except [a-zA-Z!##$%^&+=]?
Is it possible to write that regex in shorter way?
Thanks
The problem is that your .s are matching any character. To keep the convenience of using . to match a generic character but also require that the string doesn't contain any characters other than what's allowed, a simple tweak would be another lookahead at the beginning of the string to ensure that all characters before the end of the string are [a-zA-Z!##$%^&+=] or [0-9], nothing else.
Also note that [0-9] simplifies to \d, which is a bit nicer to look at:
^(?=[a-zA-Z!##$%^&+=\d]{9,}$) <rest of your regex>
You can also simplify your regex by repeating the big character set in a group, when possible, rather than writing it out manually 8 times. Also, as comment notes, when checking whether a string has enough digits, better to repeat (?:\D*\d) rather than using a dot, because you know that you want the antecedent to match non-digit characters.
Actually, because the initial lookahead above ensures that the string contains only digits and those certain non-digit characters, rather than repeating the long character set [a-zA-Z!##$%^&+=] again and again when matching a non-digit, you can just use \D, since the initial lookahead guarantees that non-digits will be within that character set.
For example:
^(?=[a-zA-Z!##$%^&+=\d]+$)(?:(?=\D*\d)(?=(?:\d*\D){8})|(?=(?:\D*\d){8})(?=\d*\D))
Explanation:
^(?=[a-zA-Z!##$%^&+=\d]{9,}$) - ensure string contains only desired characters (fail immediately if there are not at least 9 of them), then alternate between either:
(?=\D*\d)(?=(?:\d*\D){8}) - string contains at least one digit, and 8 other characters, or
(?=(?:\D*\d){8})(?=\d*\D) - string contains at least 8 digits, and at least one of the other characters
https://regex101.com/r/18xtBw/2 (to test, input only one line at a time - otherwise, the \Ds will match newline characters, which will cause problems)

RegEx No more than 2 identical consecutive characters and a-Z and 0-9

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