我目前使用此正则表达式来检查字符串是否符合一些条件。
这些条件是:字符串长度必须在8到15个字符之间;字符串中必须包含至少一个数字;字符串中必须包含至少一个大写字母;字符串中必须包含至少一个小写字母。
(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{8,15})$
它基本上工作良好,但不允许特殊字符。如果需要修改此正则表达式以允许特殊字符,请帮忙修改。谢谢!
我目前使用此正则表达式来检查字符串是否符合一些条件。
这些条件是:字符串长度必须在8到15个字符之间;字符串中必须包含至少一个数字;字符串中必须包含至少一个大写字母;字符串中必须包含至少一个小写字母。
(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{8,15})$
它基本上工作良好,但不允许特殊字符。如果需要修改此正则表达式以允许特殊字符,请帮忙修改。谢谢!
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,15}$
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z]).{8,15}$
.{8,15}
可以更加严格,如果您希望的话(例如,您可以将其更改为 \S{8,15}
来禁止空格),但请记住,这样做会降低您密码方案的强度。
我已经测试了这个模式,它按预期工作。
编辑: 一个小提示,最简单的方法是使用3个单独的正则表达式和字符串的Length
属性。这样做也更容易阅读和维护,因此如果您有选择,就应该这样做。但是,如果这是用于标记中的验证规则,则可能只能使用单个正则表达式。
正则表达式是否比更明显的方法更容易/更好地强制实施简单约束条件?
static bool ValidatePassword( string password )
{
const int MIN_LENGTH = 8 ;
const int MAX_LENGTH = 15 ;
if ( password == null ) throw new ArgumentNullException() ;
bool meetsLengthRequirements = password.Length >= MIN_LENGTH && password.Length <= MAX_LENGTH ;
bool hasUpperCaseLetter = false ;
bool hasLowerCaseLetter = false ;
bool hasDecimalDigit = false ;
if ( meetsLengthRequirements )
{
foreach (char c in password )
{
if ( char.IsUpper(c) ) hasUpperCaseLetter = true ;
else if ( char.IsLower(c) ) hasLowerCaseLetter = true ;
else if ( char.IsDigit(c) ) hasDecimalDigit = true ;
}
}
bool isValid = meetsLengthRequirements
&& hasUpperCaseLetter
&& hasLowerCaseLetter
&& hasDecimalDigit
;
return isValid ;
}
你认为三年后需要修改约束条件的维护程序员更容易理解哪种方式?
if (hasUpperCaseLetter && hasLowerCaseLetter && hasDecimalDigit) return true;
放在 foreach
里面,这样可以避免很多不必要的迭代。 - Justin Morganreturn false
,因为您已经检查了整个字符串,并且没有找到您要查找的所有内容。 - Justin Morgan你可以尝试这种方法:
private bool ValidatePassword(string password, out string ErrorMessage)
{
var input = password;
ErrorMessage = string.Empty;
if (string.IsNullOrWhiteSpace(input))
{
throw new Exception("Password should not be empty");
}
var hasNumber = new Regex(@"[0-9]+");
var hasUpperChar = new Regex(@"[A-Z]+");
var hasMiniMaxChars = new Regex(@".{8,15}");
var hasLowerChar = new Regex(@"[a-z]+");
var hasSymbols = new Regex(@"[!@#$%^&*()_+=\[{\]};:<>|./?,-]");
if (!hasLowerChar.IsMatch(input))
{
ErrorMessage = "Password should contain at least one lower case letter.";
return false;
}
else if (!hasUpperChar.IsMatch(input))
{
ErrorMessage = "Password should contain at least one upper case letter.";
return false;
}
else if (!hasMiniMaxChars.IsMatch(input))
{
ErrorMessage = "Password should not be lesser than 8 or greater than 15 characters.";
return false;
}
else if (!hasNumber.IsMatch(input))
{
ErrorMessage = "Password should contain at least one numeric value.";
return false;
}
else if (!hasSymbols.IsMatch(input))
{
ErrorMessage = "Password should contain at least one special case character.";
return false;
}
else
{
return true;
}
}
对于 Justin 上面的答案进行更新。如果你想在 MVC 中使用数据注释,可以按照以下方式操作:
[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z]).{8,15}$", ErrorMessage = "Password must be between 6 and 20 characters and contain one uppercase letter, one lowercase letter, one digit and one special character.")]
试试这个(还更正了大小写检查,因为你将它们分组为[a-zA-Z],所以只会查找至少一个小写或大写字母。所以要将它们分开):
(?!^[0-9]*$)(?!^[a-z]*$)(?!^[A-Z]*$)^(.{8,15})$
(?=^.{8,15}$)(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?!.*\s).*$
(介于8和15之间,包含至少一个数字、至少一个大写字母、至少一个小写字母且没有空格。)
我认为这样更容易理解。
我会逐个检查它们;即查找数字\d+
,然后如果失败,您可以告诉用户需要添加一个数字。这样避免了返回“无效”错误,没有提示用户出了什么问题。
public enum PasswordPolicyIssue
{
MustHaveNumber,
MustHaveCapitalLetter,
MustHaveSmallLetter,
MustBeAtLeast8Characters,
MustHaveSymbol
}
然后是验证方法,它返回布尔值并具有输出列表:
public bool MeetsPasswordPolicy(string password, out List<PasswordPolicyIssue> issues)
{
var input = password;
issues = new List<PasswordPolicyIssue>();
if (string.IsNullOrWhiteSpace(input))
throw new Exception("Password should not be empty");
var hasNumber = new Regex(@"[0-9]+");
var hasUpperChar = new Regex(@"[A-Z]+");
//var hasMiniMaxChars = new Regex(@".{8,15}");
var hasMinChars = new Regex(@".{8,}");
var hasLowerChar = new Regex(@"[a-z]+");
var hasSymbols = new Regex(@"[!@#$%^&*()_+=\[{\]};:<>|./?,-]");
if (!hasLowerChar.IsMatch(input))
issues.Add(PasswordPolicyIssue.MustHaveSmallLetter);
if (!hasUpperChar.IsMatch(input))
issues.Add(PasswordPolicyIssue.MustHaveCapitalLetter);
if (!hasMinChars.IsMatch(input))
issues.Add(PasswordPolicyIssue.MustBeAtLeast8Characters);
if (!hasNumber.IsMatch(input))
issues.Add(PasswordPolicyIssue.MustHaveNumber);
if (!hasSymbols.IsMatch(input))
issues.Add(PasswordPolicyIssue.MustHaveSymbol);
return issues.Count() ==0;
}
^^(?=.*[A-Z]{"+minUpperCase+",})(?=.*[a-z]{"+minLowerCase+",})(?=.*[0-9]{"+minNumerics+",})(?=.*[!@#$\-_?.:{]{"+minSpecialChars+",})[a-zA-Z0-9!@#$\-_?.:{]{"+minLength+","+maxLength+"}$
很长,可能可以缩短。支持特殊字符?"-_
。
\A(?=[-\?\"_a-zA-Z0-9]*?[A-Z])(?=[-\?\"_a-zA-Z0-9]*?[a-z])(?=[-\?\"_a-zA-Z0-9]*?[0-9])[-\?\"_a-zA-Z0-9]{8,15}\z
[\?\"-_a-zA-Z0-9]
中的第一个连字符会导致错误。您需要使用 [-\?\"_a-zA-Z0-9]
。 - Justin Morgan[-foo]
或 [foo-]
(或 [^-foo]
或 [^foo-]
)。 - Justin Morgan//You can set these from your custom service methods
int minLen = 8;
int minDigit 2;
int minSpChar 2;
Boolean ErrorFlag = false;
//Check for password length
if (model.NewPassword.Length < minLen)
{
ErrorFlag = true;
ModelState.AddModelError("NewPassword", "Password must be at least " + minLen + " characters long.");
}
//Check for Digits and Special Characters
int digitCount = 0;
int splCharCount = 0;
foreach (char c in model.NewPassword)
{
if (char.IsDigit(c)) digitCount++;
if (Regex.IsMatch(c.ToString(), @"[!#$%&'()*+,-.:;<=>?@[\\\]{}^_`|~]")) splCharCount++;
}
if (digitCount < minDigit)
{
ErrorFlag = true;
ModelState.AddModelError("NewPassword", "Password must have at least " + minDigit + " digit(s).");
}
if (splCharCount < minSpChar)
{
ErrorFlag = true;
ModelState.AddModelError("NewPassword", "Password must have at least " + minSpChar + " special character(s).");
}
if (ErrorFlag)
return View(model);