Regular expression password strength - regex

I have written a regular expression which could potentially be used for password strength validation:
/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!##\$%\^&\*\(\)\_])(?=.{6,})^\S*$/
My password criteria is as below:
at least 6 characters
no space
at least one digit
at least one uppercase
at least one lowercase
at least one special character: !##$%^&*()_
This is expected output:
FooBar123! should match
foobar123! should not match (no upper-case letter)
FooBar123 should not match (no special character)
F0bar! F0bar! should not match (contains spaces)
Fo0* should not match (too short)
For some reason all the tests passed except FooBar123! . Any idea why is it like that? Thank you.

You can try the below regex and the condition can be implemented over the response of this expression
^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!##\$%\^&\*\(\)\_])(?=.{6,})^\S*$

Related

Altering Regex to allow apostrophe in email address

At work, our current ValidationExpression looks horrible and very confusing for me. We are using the WebForms <asp:RegularExpressionValidator> user control which looks like this:
<asp:RegularExpressionValidator ID="regEmail" runat="server"
ValidationGroup="EditEmails"
Text="*" ErrorMessage="Invalid email address."
ControlToValidate="txtAdd"
Display="Dynamic"
ValidationExpression="^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+#((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$"/>
I need to somehow alter this to allow apostrophes ( ' ) inside an email because at the moment this expression is failing.
Example of an email that needs to pass this validation: Test.O'neill#example.co.uk
I am unsure what the expression does but I'm sure this could be made shorter (maybe not simpler but that does not matter as long as it works).
Anyone know of a better regular expression I could use which works against valid emails and takes this into consideration? Thank you!
EDIT: My question is different because the proposed duplicate question does not work for VB.Net RegularExpression Validator user control.
See regex in use here
^([a-z\d]+[_+.-])*[a-z\d']+#(\w+[.-])*\w{1,63}\.[a-z]+$
^ Assert position at the start of the line
([a-z\d]+[_+.-])* Capture the following any number of times
[a-z\d]+ Match any ASCII letter or digit one or more times (also matches uppercase variants with i flag enabled)
[_+.-] Match any character in the set
[a-z\d']+ Match any ASCII letter, digit, or apostrophe one or more times
# Match this literally
(\w+[.-])* Capture the following any number of times
\w+ Match any word character one or more times
[.-] Match any character in the set
\w{1,63} Match any word character between one and 63 times
\. Match a literaly dot .
[a-z]+ Match any ASCII letter one or more times
$ Assert position at the end of the line
To implement the above pattern in a case-insensitive manner, add the RegexOptions.IgnoreCase flag. For more information see this post.

regular expression to find a string that always contains 6 characters, CAPITALS and numbers only

I've been trying to catch a string (6 characters) like ABC123 (or any combination of Capitals and numbers) using a regular expression. I can catch ABCDE1 or 1ABCDE or even AC34FG. As long as the string contains at least 1 CAPITAL and 1 number the regular expression works just fine. But something like ABCDEF or 123456 does not! What am I missing? The regular expression I use is:
(?<=\t)([0-9]+[A-Z]+|[A-Z]+[0-9]+)[0-9A-Z]*(?=\t)
Any help would be appreciated! Thanks!
In your (?<=\t)([0-9]+[A-Z]+|[A-Z]+[0-9]+)[0-9A-Z]*(?=\t) pattern, you explicitly require at least 1 digit to be followed with at least 1 letter (with [0-9]+[A-Z]+) (and vice versa with [A-Z]+[0-9]+) only in between tab chars.
To just match any 6 char substring in between tabs that consists of uppercase ASCII letters or digits, you may use
(?<=\t)[A-Z0-9]{6}(?=\t)
See this regex demo.
Or, to also match at the start/end of string:
(?<![^\t])[A-Z0-9]{6}(?![^\t])
See another regex demo.
If i understand you correctly, your aproach is way too complicated.
/\b[A-Z0-9]{6}\b/
Catches any (exact) 6 character string, as long as either capitals or numbers or both are present.
Note the \b part as a word boundary, you could change these delimiters to whatever fits your need.
Another word of warning: A-Z captures only 26 uppercase characters, Umlauts or accented characters will not be cought here, use something like \p{L} if your engine supports it and your data requires it. See https://www.regular-expressions.info/unicode.html for more details.

Regex building multicase-required pattern issue

I'm try to build regex pattern which requires the string to contain multicase letters together, but there's no success.
Here's what I have, but it doesn't work:
(?=[A-Z]+)(?=[a-z]+)(?=[0-9]+)
In other words, the string should to match only if it contains uppercase and lowercase and digits in any order like that:
MyPass777 <-- match
Mypass777 <-- match
MyPass <-- no match
mypass777 <-- no match
So, how to let this work?
Your positive lookaheads must also use .* before your conditions to allow for any arbitrary number of character before letter or numbers:
\b(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])[A-Za-z0-9]+\b
RegEx Demo
Also note use of \b (word boundary) on either side of your regex to make sure to match complete words only.
If you want a yes/no test, then use alternation.
Require something that has a upper and eventually a lower OR something that has a lower and eventually a upper.
With spaces added for clarity
(?: [a-z].*[A-Z] | [A-Z].*[a-z] )
With a third requirement, numbers, it gets combinatorially more expensive.
You're better off testing in three phases. Does this have a uppercase? If not, fail. Does it have a lowercase? If not, fail. Does it have a number? If not, fail. Else, it's okay.
Use separate regexes instead of single regex to gain additional benefits.
With this approach, you do not limit user to enter uppercase+lowercase+digits, but if they use for example uppercase+lowercase+punctation, the password will be considered equally good.
Test 4 cases:
[A-Z]
[a-z]
[0-9]
[\!+\-*##$%\^&*[\]{}:";'<>?,./] ' or refer to Unicode character class P (punctuation) instead
Now count matching cases.
1-2 cases: weak password.
3 cases: good password.
4 cases: strong password.
This pattern does forward lookahead and requires that the next character be an uppercase letter, a lowercase letter, and a digit at the same time. It never matches.
You want something like
(?=\w*[A-Z])(?=\w*[a-z])(?=\w*[0-9])(\w+\b)
At least, that's my best understanding of your problem: You want a string of alphanumeric characters that contains at least one uppercase letter, at least one lowercase letter, and at least one digit.

Building Password Validation Regex Dynamically

I'm working on some legacy code, found a regex and was hoping someone could dissect it for me:
((?=.*[^a-zA-Z])(?=.*[a-z])(?=.*[A-Z]).{8,})
I know what it's doing, but not entirely sure how it's doing it. What exactly is the "." doing after the conditions?
I'm trying to add some code to generate this regex dynamically. That is, if a bunch of configuration says the password can do anything, I want to return a regex that will return true for ALL CALLS OF .matches() in groovy. So far I've just done string formatting, so the regex created is "(.)", however this is returning false when called with matches().
Thanks for the help!
Here's the explanation broken down for you and a couple example strings.
http://regex101.com/r/oZ6dK4
the tl;dr here, is using the lookahead assertions, it's requiring that at least somewhere in the string you have:
a lowercase letter [a-z]
an uppercase letter [A-Z]
a NON-letter [^a-zA-Z]
and that it must be at least 8 characters {8,}
This looks like a password requirements validator to me.
Strings it will match:
asdfsdklj2-3049-09AS
09809LK2JL23Lsdf
Strings it won't match:
asdfsdf
2398-02934
23Abs
As for your question about the dot (.): it's not a period, it's a regex special character that matches anything except newline. (In the regex101 explanation you can see it states .{8,} matches any character (except newline)). In this case, the reason ~"(.)".matches() returns false, is because it requires a minimum of 8 characters in order to validate.
This checks to ensure the password contains a non-alphabetic character, that it contains at least one lowercase and uppercase alphabetic character, and finally that the entire string is at least 8 characters in length. The latter portion is where the . comes in – matching the entire string and ensuring it's 8+ characters.
(?=.*[^a-zA-Z) - this checks that there is a non-alpha character somewhere in the password
(?=.*[a-z]) - this checks that there is a lower case character in the password somewhere
(?=.*[A-Z]) - this checks that there is an upper case character in the password somewhere
.{8,} - this checks that there are at least 8 characters.
?= is the positive lookahead. The regex in this bracket must be matched and it must occur after this spot in the input.
Check rexegg.com for all kinds of useful regex information and a quick reference that's very useful.

Regex for alphanumeric, but at least one letter

In my ASP.NET page, I have an input box that has to have the following validation on it:
Must be alphanumeric, with at least one letter (i.e. can't be ALL
numbers).
^\d*[a-zA-Z][a-zA-Z0-9]*$
Basically this means:
Zero or more ASCII digits;
One alphabetic ASCII character;
Zero or more alphanumeric ASCII characters.
Try a few tests and you'll see this'll pass any alphanumeric ASCII string where at least one non-numeric ASCII character is required.
The key to this is the \d* at the front. Without it the regex gets much more awkward to do.
Most answers to this question are correct, but there's an alternative, that (in some cases) offers more flexibility if you want to change the rules later on:
^(?=.*[a-zA-Z].*)([a-zA-Z0-9]+)$
This will match any sequence of alphanumerical characters, but only if the first group also matches the whole sequence. It's a little-known trick in regular expressions that allows you to handle some very difficult validation problems.
For example, say you need to add another constraint: the string should be between 6 and 12 characters long. The obvious solutions posted here wouldn't work, but using the look-ahead trick, the regex simply becomes:
^(?=.*[a-zA-Z].*)([a-zA-Z0-9]{6,12})$
^[\p{L}\p{N}]*\p{L}[\p{L}\p{N}]*$
Explanation:
[\p{L}\p{N}]* matches zero or more Unicode letters or numbers
\p{L} matches one letter
[\p{L}\p{N}]* matches zero or more Unicode letters or numbers
^ and $ anchor the string, ensuring the regex matches the entire string. You may be able to omit these, depending on which regex matching function you call.
Result: you can have any alphanumeric string except there's got to be a letter in there somewhere.
\p{L} is similar to [A-Za-z] except it will include all letters from all alphabets, with or without accents and diacritical marks. It is much more inclusive, using a larger set of Unicode characters. If you don't want that flexibility substitute [A-Za-z]. A similar remark applies to \p{N} which could be replaced by [0-9] if you want to keep it simple. See the MSDN page on character classes for more information.
The less fancy non-Unicode version would be
^[A-Za-z0-9]*[A-Za-z][A-Za-z0-9]*$
^[0-9]*[A-Za-z][0-9A-Za-z]*$
is the regex that will do what you're after. The ^ and $ match the start and end of the word to prevent other characters. You could replace the [0-9A-z] block with \w, but i prefer to more verbose form because it's easier to extend with other characters if you want.
Add a regular expression validator to your asp.net page as per the tutorial on MSDN: http://msdn.microsoft.com/en-us/library/ms998267.aspx.
^\w*[\p{L}]\w*$
This one's not that hard. The regular expression reads: match a line starting with any number of word characters (letters, numbers, punctuation (which you might not want)), that contains one letter character (that's the [\p{L}] part in the middle), followed by any number of word characters again.
If you want to exclude punctuation, you'll need a heftier expression:
^[\p{L}\p{N}]*[\p{L}][\p{L}\p{N}]*$
And if you don't care about Unicode you can use a boring expression:
^[A-Za-z0-9]*[A-Za-z][A-Za-z0-9]*$
^[0-9]*[a-zA-Z][a-zA-Z0-9]*$
Can be
any number ended with a character,
or an alphanumeric expression started with a character
or an alphanumeric expression started with a number, followed by a character and ended with an alphanumeric subexpression