我想要一个正则表达式来检查
密码必须为 8 个字符,包括 1 个大写字母、1 个特殊字符和字母数字字符。
这是我的验证表达式,它适用于八个字符,包括一个大写字母、一个小写字母和一个数字或特殊字符。
(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$"
我如何为必须为八个字符(包括一个大写字母、一个特殊字符和字母数字字符)的密码编写它?
你所追求的正则表达式很可能是巨大的,而且对于那些不熟悉正则表达式的人来说,维护起来是一场噩梦。
我认为将你的正则表达式分解并一次做一点会更容易。可能需要做更多的工作,但我很确定维护和调试它会更容易。这也将允许您向您的用户(不仅仅是 Invalid Password
)提供更多有针对性的错误消息,从而改善用户体验。
从我所看到的情况来看,您对正则表达式非常流利,所以我认为给您正则表达式来做您需要的事情是徒劳的。
看到你的评论,我会这样做:
必须是八个字符长:您不需要正则表达式。使用 .Length 属性就足够了。
包括一个大写字母:可以使用 [AZ]+ 正则表达式。如果字符串至少包含一个大写字母,则此正则表达式将返回 true。
一个特殊字符:您可以使用 \W 来匹配任何不是字母或数字的字符,或者,您可以使用类似 [!@#] 的东西来指定特殊字符的自定义列表。请注意,尽管 $、^、( 和 ) 等字符是正则表达式语言中的特殊字符,因此需要像这样对它们进行转义:\$。简而言之,您可以使用 \W。
字母数字字符:使用 \w+ 应该匹配任何字母和数字以及下划线。
查看 this 教程了解更多信息。
( # Start of group
(?=.*\d) # must contain at least one digit
(?=.*[A-Z]) # must contain at least one uppercase character
(?=.*\W) # must contain at least one special symbol
. # match anything with previous condition checking
{8,8} # length is exactly 8 characters
) # End of group
在一行中:
((?=.*\d)(?=.*[A-Z])(?=.*\W).{8,8})
编辑 2019-05-28:
您需要匹配整个输入字符串。因此,您可以将正则表达式括在 ^
和 $
之间,以防止意外地将部分匹配假设为匹配整个输入:
^((?=.*\d)(?=.*[A-Z])(?=.*\W).{8,8})$
资料来源:
密码匹配表达式
使用正则表达式验证密码强度
^
和 $
之间。试试这个:^((?=.*\d)(?=.*[A-Z])(?=.*\W).{8,8})$
这么多答案....都不好!
正则表达式没有 AND 运算符,因此很难编写匹配有效密码的正则表达式,当有效性由某物和其他东西和其他东西定义时......
但是,正则表达式确实有一个 OR 运算符,所以只需应用 DeMorgan 定理,并编写一个匹配无效密码的正则表达式。
任何少于 8 个字符的内容或任何没有数字的内容或任何没有大写的内容或任何没有特殊字符的内容
所以:
^(.{0,7}|[^0-9]*|[^A-Z]*|[a-zA-Z0-9]*)$
如果有任何匹配,那么它是一个无效的密码。
|.{9,}
。 +1 的概念
答案是不使用正则表达式。这是集合和计数。
正则表达式是关于顺序的。
在你作为程序员的生活中,你会被要求做很多没有意义的事情。学会更深层次地挖掘。了解问题何时出错。
问题(如果它提到正则表达式)是错误的。
伪代码(最近在太多语言之间切换):
if s.length < 8:
return False
nUpper = nLower = nAlphanum = nSpecial = 0
for c in s:
if isUpper(c):
nUpper++
if isLower(c):
nLower++
if isAlphanumeric(c):
nAlphanum++
if isSpecial(c):
nSpecial++
return (0 < nUpper) and (0 < nAlphanum) and (0 < nSpecial)
打赌您几乎立即阅读并理解了上述代码。打赌您使用正则表达式的时间要长得多,并且不太确定它是否正确。扩展正则表达式是有风险的。扩展了上面的内容,更不用说。
还要注意这个问题的措辞不准确。字符集是 ASCII 还是 Unicode,还是 ??我从阅读这个问题的猜测是至少假设一个小写字符。所以我认为假设的最后一条规则应该是:
return (0 < nUpper) and (0 < nLower) and (0 < nAlphanum) and (0 < nSpecial)
(改变帽子以安全为重点,这是一个非常烦人/无用的规则。)
学会知道什么时候问题是错误的,比聪明的答案更重要。对错误问题的聪明回答几乎总是错误的。
例如,如何使用可读/可维护的正则表达式来完成。
对于更长的正则表达式,您应该始终使用 RegexOptions.IgnorePatternWhitespace
来允许表达式中的空格和注释以提高可读性。
String[] passwords = { "foobar", "Foobar", "Foobar1", "Fooobar12" };
foreach (String s in passwords) {
Match password = Regex.Match(s, @"
^ # Match the start of the string
(?=.*\p{Lu}) # Positive lookahead assertion, is true when there is an uppercase letter
(?=.*\P{L}) # Positive lookahead assertion, is true when there is a non-letter
\S{8,} # At least 8 non whitespace characters
$ # Match the end of the string
", RegexOptions.IgnorePatternWhitespace);
if (password.Success) {
Console.WriteLine(s + ": valid");
}
else {
Console.WriteLine(s + ": invalid");
}
}
Console.ReadLine();
lookahead assertion
作为一种“和”模式以覆盖单个正则表达式中的整个约束的最佳方式。适用于更多约束,如果应通过配置启用/禁用某些约束,则可以轻松生成。
如果您只需要一个大写字母和特殊字符,那么这应该可以工作:
@"^(?=.{8,}$)(?=[^A-Z]*[A-Z][^A-Z]*$)\w*\W\w*$"
AAaaaaaaa#
不正确
您要查找的正则表达式是:/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*\[\]"\';:_\-<>\., =\+\/\\]).{8,}$/u
。
示例和测试:http://regexr.com/3fhr4
{8,}
之前的 .
更改为 [^\s]
。
这个问题开始流行起来,出现了很多有趣的建议。
是的,手写很难。所以更简单的解决方案是使用模板。尽管生成的正则表达式可能不是最佳的,但它会更容易维护和/或更改,并且用户将对结果有更好的控制。我可能错过了一些东西,所以任何建设性的批评都会有所帮助。
此链接可能很有趣:match at least 2 digits 2 letters in any order in a string、Regular Expression Language、Capturing groups
我根据我在 SO 中看到的所有正则表达式使用此模板 (?=(?:.*?({type})){({count})})
。下一步是替换所需的模式 ( number
, special character
... ) 并添加长度配置。
我为编写正则表达式做了一个小课 PasswordRegexGenerator.cs 一个例子:
string result = new PasswordRegexGenerator ( )
.UpperCase ( 3, -1 ) // ... {3,}
.Number ( 2, 4 ) // ... {2,4}
.SpecialCharacter ( 2 ) // ... {2}
.Total ( 8,-1 )
.Compose ( );
/// <summary>
/// Generator for regular expression, validating password requirements.
/// </summary>
public class PasswordRegexGenerator
{
private string _elementTemplate = "(?=(?:.*?({type})){({count})})";
private Dictionary<string, string> _elements = new Dictionary<string, string> {
{ "uppercase", "[A-Z]" },
{ "lowercase", "[a-z]" },
{ "number", @"\d" },
{ "special", @"\W" },
{ "alphanumeric", @"\w" }
};
private StringBuilder _sb = new StringBuilder ( );
private string Construct ( string what, int min, int max )
{
StringBuilder sb = new StringBuilder ( _elementTemplate );
string count = min.ToString ( );
if ( max == -1 )
{
count += ",";
}
else if ( max > 0 )
{
count += "," + max.ToString();
}
return sb
.Replace ( "({type})", what )
.Replace ( "({count})", count )
.ToString ( );
}
/// <summary>
/// Change the template for the generation of the regex parts
/// </summary>
/// <param name="newTemplate">the new template</param>
/// <returns></returns>
public PasswordRegexGenerator ChangeRegexTemplate ( string newTemplate )
{
_elementTemplate = newTemplate;
return this;
}
/// <summary>
/// Change or update the regex for a certain type ( number, uppercase ... )
/// </summary>
/// <param name="name">type of the regex</param>
/// <param name="regex">new value for the regex</param>
/// <returns></returns>
public PasswordRegexGenerator ChangeRegexElements ( string name, string regex )
{
if ( _elements.ContainsKey ( name ) )
{
_elements[ name ] = regex;
}
else
{
_elements.Add ( name, regex );
}
return this;
}
#region construction methods
/// <summary>
/// Adding number requirement
/// </summary>
/// <param name="min"></param>
/// <param name="max"></param>
/// <returns></returns>
public PasswordRegexGenerator Number ( int min = 1, int max = 0 )
{
_sb.Append ( Construct ( _elements[ "number" ], min, max ) );
return this;
}
public PasswordRegexGenerator UpperCase ( int min = 1, int max = 0 )
{
_sb.Append ( Construct ( _elements[ "uppercase" ], min, max ) );
return this;
}
public PasswordRegexGenerator LowerCase ( int min = 1, int max = 0 )
{
_sb.Append ( Construct ( _elements[ "lowercase" ], min, max ) );
return this;
}
public PasswordRegexGenerator SpecialCharacter ( int min = 1, int max = 0 )
{
_sb.Append ( Construct ( _elements[ "special" ], min, max ) );
return this;
}
public PasswordRegexGenerator Total ( int min, int max = 0 )
{
string count = min.ToString ( ) + ( ( max == 0 ) ? "" : "," + max.ToString ( ) );
_sb.Append ( ".{" + count + "}" );
return this;
}
#endregion
public string Compose ()
{
return "(" + _sb.ToString ( ) + ")";
}
}
您可以使用以下类进行验证:
public class PasswordValidator{
private Pattern pattern;
private Matcher matcher;
private static final String PASSWORD_PATTERN =
"((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{6,20})";
public PasswordValidator(){
pattern = Pattern.compile(PASSWORD_PATTERN);
}
/**
* Validate password with regular expression
* @param password password for validation
* @return true valid password, false invalid password
*/
public boolean validate(final String password){
matcher = pattern.matcher(password);
return matcher.matches();
}
}
其中 6 和 20 是密码的最小和最大长度。
如果密码至少有 8 个字符,则首先使用非回溯表达式匹配整个密码(这样,长但无效的密码不会出现组合爆炸): (?>{8,})
使用后向断言来检查是否存在所有必需的字符(AND 条件)。 (?<=...)
至少一个大写字符:(?<=\p{Lu}.*)
至少一个特殊字符(有点模棱两可,但让我们使用非单词): (?<=\W.*)
至少一个字母数字字符 (: (?<=\w.*)
总结:
(?>.{8,})(?<=\p{Lu}.*)(?<=\W.*)(?<=\w.*)
最好不要对所有事情都使用正则表达式。这些要求很轻。在 CPU 方面检查标准/验证的字符串操作比正则表达式更便宜、更快!
我找到的至少有 8 个字符,由至少 1 个小写字母和 1 个大写字母以及 1 个数字和 1 个符号组成。
^((?=.*\d)(?=.*[A-Z])(?=.*\W).{8,})$
var regex =/^(?=.*\d)(?=.*[!@#$%^&*])(?=.*[az])(?=.*[AZ]).{8 ,64}$/; function test() { if(regex.test(document.getElementById("txtPassword").value)===false) { alert("Min 6,Max 64,至少一个大写字符,一个小写字符,一个数值和一个特殊字符(!@#$%^&*) 必填"); } else { 警报(“成功”); } }
/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}$/
[A-Z]
(没有+
)是否足够?由于您只是检查密码中是否存在至少一个,因此您只需要匹配一个(而不是一行中的多个)。