我有一个正在构建的应用程序的密码正则表达式,其目的是:
确保用户使用6到12个字符。
确保用户使用一个特殊字符或一个数字。
此外,它不区分大小写。
应用程序在.net中我有以下正则表达式:
I have the following regex for the password checker, bit lengthy but for your viewing if you feel any of this is wrong please let me know.
^(?=.*\d)(?=.*[A-Za-z]).{6-12}$|^(?=.*[A-Za-z])(?=.*[!#$%&'\(\)\*\+-\.:;<=>\?@\[\\\]\^_`\{\|\}~0x0022]|.*\s).{6,12}$
正好打破正则表达式,确保你们都高兴它是正确的。
^ = start of string ”^”
(?=.*\d) = must contain “?=” any set of characters “.*” but must include a digit “\d”.
(?=.*[A-Za-z]) = must contain “?=” any set of characters “.*” but must include an insensitive case letter.
.{6-12}$ = must contain any set of characters “.” but must have between 6-12 characters and end of string “$”.
|^ = or “|” start of string “^”
(?=.*[A-Za-z]) = must contain “?=” any set of characters “.*” but must include an insensitive case letter.
(?=.*[!#$%&'\(\)\*\+-\.:;<=>\?@\[\\\]\^_`\{\|\}~0x0022]|.*\s) = must contain “?=” any set of characters “.*” but must include at least special character we have defined or a space ”|.*\s)”. “0x0022” is Unicode for single quote “ character.
.{6,12}$ = set of characters “.” must be between 6 – 12 and this is the end of the string “$”
这是漫长的啰嗦,似乎正在做这项工作,但我想知道是否有更简单的方法来编写这种正则表达式,我想知道如果可能的话我如何缩短它?
感谢高级。
答案 0 :(得分:6)
它必须是正则表达式吗?查看要求,您只需String.Length
和String.IndexOfAny()
。
答案 1 :(得分:3)
首先,好好为你的正则表达式提供评论。但是,有一个更好的方法。只需在自由间隔模式下从一开始就编写正则表达式,并附带大量注释。这样,您就可以在源代码中记录正则表达式(并在有大量括号时提供缩进以提高可读性)。以下是我用C#代码编写原始正则表达式的方法:
if (Regex.IsMatch(usernameString,
@"# Validate username having a digit and/or special char.
^ # Either... Anchor to start of string.
(?=.*\d) # Assert there is a digit AND
(?=.*[A-Za-z]) # assert there is an alpha.
.{6-12} # Match any name with length from 6 to 12.
$ # Anchor to end of string.
| ^ # Or... Anchor to start of string
(?=.*[A-Za-z]) # Assert there is an alpha AND
(?=.* # assert there is either a special char
[!#$%&'\(\)\*\+-\.:;<=>\?@\[\\\]\^_`\{\|\}~\x22]
| .*\s # or a space char.
) # End specialchar-or-space assertion.
.{6-12} # Match any name with length from 6 to 12.
$ # Anchor to end of string.
", RegexOptions.IgnorePatternWhitespace)) {
// Valid username.
} else {
// Invalid username.
}
上面的代码段使用了首选的@"..."
字符串语法,简化了元字符的转义。这个原始正则表达式错误地使用破折号分隔大括号量词的两个数字,即.{6-12}
。正确的语法是用逗号分隔这些数字,即.*{6,12}
。 (也许.NET允许使用.{6-12}
语法?)我还将0x0022
("
双引号字符)更改为\x22
。
那就是说,原来的正则表达式可以改进一下:
if (Regex.IsMatch(usernameString,
@"# Validate username having a digit and/or special char.
^ # Anchor to start of string.
(?=.*?[A-Za-z]) # Assert there is an alpha.
(?: # Group for assertion alternatives.
(?=.*?\d) # Either assert there is a digit
| # or assert there is a special char
(?=.*?[!#$%&'()*+-.:;<=>?@[\\\]^_`{|}~\x22\s]) # or space.
) # End group of assertion alternatives.
.{6,12} # Match any name with length from 6 to 12.
$ # Anchor to end of string.
", RegexOptions.IgnorePatternWhitespace)) {
// Valid username.
} else {
// Invalid username.
}
此正则表达式消除了全局替代方案,而是使用非捕获组来表示“digit或specialchar”断言替代方案。此外,您可以通过简单地将\s
添加到特殊字符列表中来消除“特殊字符或空格”备选方案的非捕获组。我还为断言中的点星添加了一个惰性修饰符,即.*?
- (这可能使正则表达式匹配更快一些。)从specialchar字符类中删除了一堆不必要的转义符。
但正如Stema巧妙地指出的那样,你可以将数字和特殊字符组合起来进一步简化:
if (Regex.IsMatch(usernameString,
@"# Validate username having a digit and/or special char.
^ # Anchor to start of string
(?=.*?[A-Za-z]) # Assert there is an alpha.
# Assert there is a special char, space
(?=.*?[!#$%&'()*+-.:;<=>?@[\\\]^_`{|}~\x22\s\d]) # or digit.
.{6,12} # Match any name with length from 6 to 12.
$ # Anchor to end of string.
", RegexOptions.IgnorePatternWhitespace)) {
// Valid username.
} else {
// Invalid username.
}
除此之外,您的原始正则表达式在准确性方面确实没有任何问题。但是,从逻辑上讲,这个公式允许用户名以空格结尾,这可能不是一个好主意。我还会在名称中明确指定允许字符的白名单,而不是使用过度宽容的"."
点。
答案 2 :(得分:2)
我不确定你的行为是否合理,但要实现这一点,你的正则表达式可以更简单
^(?=.*[A-Za-z])(?=.*[\d\s!#$%&'\(\)\*\+-\.:;<=>\?@\[\\\]\^_`\{\|\}~0x0022]).{6,12}$
为何使用替代品?只需将\d
和\s
添加到角色类。