Say I have a regex that checks for alphanumeric.
I now want to create another regex that checks for at least 1 number in the password.
And I want to check if it has at least 1 non-alphanumeric character (somethign other than a letter or number).
Should I just call each one seperatley, and if one fails return false or is there a way to combine them into 1 call?
Depends on exactly what criteria you're using, but it would probably be better to do a single pass through the string and set a number of flags based on what you've seen:
- hasDigit
- hasAlpha
- hasSymbol
- etc
Then use these at the end to decide if the password is complex enough.
Even Better:
As lexu suggests, using counts instead of flags would allow greater flexibility.
I would compose small methods using &&:
internal bool HasDigit(string password) { .. }
internal bool HasNonAlpha(string password) { .. }
bool IsStrong(string password) {
return HasDigit(password) && HasNonAlpha(password);
}
I think this is what you're looking for:
^.{6,}(?<=\d.*)(?<=[^a-zA-Z0-9].*)$
(will match a password with a minimum length of 6, with at least one digit and one non-alphanumerical character)
In code:
public bool PasswordOk(string pwd)
{
return Regex.IsMatch(pwd,@"^.{6,}(?<=\d.*)(?<=[^a-zA-Z0-9].*)$");
}
You should use two calls. For a bit more advanced testing you can use The password meter. It is freely available for distribution under GPL.
IMHO, it's a question of style whether to make one or two statements from it.
Why not check for it in any of the two orders that they may appear. (As regular expressions go, we don't have something like a counter for braces or parantheses, thus we have to honor the possible ordering of things.
That one might work for perl:
(\d.*[^[:alnum:]])|([^[:alnum:]].*\d)
Might be easier to read to make two statements from it, especially because then every semantical condition is only occurring once.
You add an | (or) operator into the regex e.g.
[0-9]|[A-Z]
Regex is not the fastest way.
Give this a try:
string Password = "Pass12!";
bool ValidPassword = Password.Any(char.IsDigit)
&& !Password.All(char.IsLetterOrDigit)
&& Password.Length >= 6;
Instead of:
string Password = "Pass12!";
bool ValidPassword = Regex.IsMatch(Password, @"^.{6,}(?<=\d.*)(?<=[^a-zA-Z0-9].*)$");
I you iterate through it 1 million times it will take the first 157ms and the second 1251ms.
And the most important thing the others said already: much better to maintain.