正则表达式是:
^.*(?=.{8,})(?=..*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$
密码策略如下:
至少8个字符
包含至少一个数字
包含至少一个小写字母和一个大写字母
包含至少一个特殊字符 (
@#%$^
等)不包含空格、制表符等
我缺失的是第5点。我无法让正则表达式检查空格、制表符、回车等等。
有人可以帮忙吗?
试试这个:
^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$
解释:
^ # start-of-string
(?=.*[0-9]) # a digit must occur at least once
(?=.*[a-z]) # a lower case letter must occur at least once
(?=.*[A-Z]) # an upper case letter must occur at least once
(?=.*[@#$%^&+=]) # a special character must occur at least once
(?=\S+$) # no whitespace allowed in the entire string
.{8,} # anything, at least eight places though
$ # end-of-string
每个规则都是独立的“模块”,因此很容易添加、修改或删除单个规则。
(?=.*[xyz])
结构会匹配整个字符串(.*
),并回溯到第一个出现[xyz]
可以匹配的位置。如果找到了[xyz]
它会成功,否则它会失败。
另一种选择是使用懒惰限定符:(?=.*?[xyz])
。对于密码检查,这几乎没有任何影响,在更长的字符串中,它可能是更有效的变体。
当然,最有效的变体(但最难阅读和维护,因此最容易出错)是(?=[^xyz]*[xyz])
。对于这个长度和目的的正则表达式,我不建议使用它,因为它没有真正的好处。
\\s
。这是Java的要求,而不是正则表达式的要求。 - Tomalak(?=...)
模式,以便它与表达式的其余部分相匹配。 - Tomalak(?=\S+$)
)还是“不包含空格字符”((?!.*\s)
),都是个人偏好的问题。使用你更喜欢的即可 :) - Tomalak使用正则表达式的简单示例
public class passwordvalidation {
public static void main(String[] args) {
String passwd = "aaZZa44@";
String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}";
System.out.println(passwd.matches(pattern));
}
}
解释:
(?=.*[0-9])
必须至少出现一次数字(?=.*[a-z])
必须至少出现一个小写字母(?=.*[A-Z])
必须至少出现一个大写字母(?=.*[@#$%^&+=])
必须至少出现一个特殊字符(@#$%^&+=)(?=\\S+$)
整个字符串中不能有空格.{8,}
至少8个字符之前给出的所有答案都使用了相同(正确的)技巧,为每个需求使用单独的前瞻。但它们包含一些低效和一个潜在的巨大错误,具体取决于实际使用密码的后端。
我将从已接受的答案中提取正则表达式:
^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$
首先,由于Java支持\A
和\z
,我更喜欢使用它们来确保整个字符串得到验证,而不受Pattern.MULTILINE
的影响。这不会影响性能,但可以避免在重复使用正则表达式时出现错误。
\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}\z
通过在允许字符的简写 \S
上放置变量量词 {8,}
,可以一次性完成检查密码是否包含空格和检查其最小长度的操作:
\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])\S{8,}\z
如果提供的密码包含空格,则所有检查都将进行,但最终检查会因为空格而失败。可以通过使用\S
替换所有点来避免这种情况:\A(?=\S*[0-9])(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[@#$%^&+=])\S{8,}\z
仅当您确实希望允许任何字符时,才应使用点。否则,请使用(非)字符类将您的正则表达式限制为仅允许那些真正允许的字符。虽然在这种情况下几乎没有区别,但是在更适当的情况下不使用点是一个很好的习惯。我看到有太多的因为开发人员懒得使用比点更合适的东西而导致灾难性回溯的情况。
由于在密码的前半部分找到合适的字符的机会很大,所以使用懒惰量词可能更有效:
\A(?=\S*?[0-9])(?=\S*?[a-z])(?=\S*?[A-Z])(?=\S*?[@#$%^&+=])\S{8,}\z
但现在是真正重要的问题:没有任何答案提到原始问题似乎是由一个使用ASCII字符集思维的人编写的。但在Java中,字符串是Unicode编码。密码中是否允许非ASCII字符?如果允许,只有ASCII空格被禁止,还是应该排除所有Unicode空白符?
默认情况下,\s
仅匹配ASCII空白符,因此它的反义词\S
匹配所有Unicode字符(无论是否为空格)和所有非空白ASCII字符。如果允许Unicode字符但不允许Unicode空格,则可以指定UNICODE_CHARACTER_CLASS
标志,使\S
排除Unicode空格。如果不允许Unicode字符,则可以使用[\x21-\x7E]
替代\S
来匹配所有不是空格或控制字符的ASCII字符。
这就带来了下一个潜在问题:我们是否想允许控制字符?撰写正确的正则表达式的第一步是明确指定您要匹配的内容和不匹配的内容。唯一100%技术上正确的答案是,问题中的密码规范不明确,因为它没有说明是否允许某些字符范围,例如控制字符或非ASCII字符。
如果可能的话,不应该使用过于复杂的正则表达式,因为它们:
虽然使用许多小正则表达式可能会带来一些性能开销,但以上所述优点很容易超越它。
我会这样实现:
bool matchesPolicy(pwd) {
if (pwd.length < 8) return false;
if (not pwd =~ /[0-9]/) return false;
if (not pwd =~ /[a-z]/) return false;
if (not pwd =~ /[A-Z]/) return false;
if (not pwd =~ /[%@$^]/) return false;
if (pwd =~ /\s/) return false;
return true;
}
感谢所有答案,基于它们但扩展了特殊字符:
@SuppressWarnings({"regexp", "RegExpUnexpectedAnchor", "RegExpRedundantEscape"})
String PASSWORD_SPECIAL_CHARS = "@#$%^`<>&+=\"!ºª·#~%&'¿¡€,:;*/+-.=_\\[\\]\\(\\)\\|\\_\\?\\\\";
int PASSWORD_MIN_SIZE = 8;
String PASSWORD_REGEXP = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[" + PASSWORD_SPECIAL_CHARS + "])(?=\\S+$).{"+PASSWORD_MIN_SIZE+",}$";
单元测试:
Passwords must include characters from at least two (2) of these groupings: alpha, numeric, and special characters.
^.*(?=.{8,})(?=.*\d)(?=.*[a-zA-Z])|(?=.{8,})(?=.*\d)(?=.*[!@#$%^&])|(?=.{8,})(?=.*[a-zA-Z])(?=.*[!@#$%^&]).*$
我测试过了,它可以正常工作
^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=\S+$).*[A-Za-z0-9].{8,}$
如果有人对每种类型的字符的最低要求感兴趣,我建议在Tomalak的答案基础上进行以下扩展:
^(?=(.*[0-9]){%d,})(?=(.*[a-z]){%d,})(?=(.*[A-Z]){%d,})(?=(.*[^0-9a-zA-Z]){%d,})(?=\S+$).{%d,}$
为您准备了带参数的Java方法
只需复制粘贴并设置所需参数即可。
如果您不想要一个模块,只需像我一样对特殊字符添加注释或"if"语句。
//______________________________________________________________________________
/**
* Validation Password */
//______________________________________________________________________________
private static boolean validation_Password(final String PASSWORD_Arg) {
boolean result = false;
try {
if (PASSWORD_Arg!=null) {
//_________________________
//Parameteres
final String MIN_LENGHT="8";
final String MAX_LENGHT="20";
final boolean SPECIAL_CHAR_NEEDED=true;
//_________________________
//Modules
final String ONE_DIGIT = "(?=.*[0-9])"; //(?=.*[0-9]) a digit must occur at least once
final String LOWER_CASE = "(?=.*[a-z])"; //(?=.*[a-z]) a lower case letter must occur at least once
final String UPPER_CASE = "(?=.*[A-Z])"; //(?=.*[A-Z]) an upper case letter must occur at least once
final String NO_SPACE = "(?=\\S+$)"; //(?=\\S+$) no whitespace allowed in the entire string
//final String MIN_CHAR = ".{" + MIN_LENGHT + ",}"; //.{8,} at least 8 characters
final String MIN_MAX_CHAR = ".{" + MIN_LENGHT + "," + MAX_LENGHT + "}"; //.{5,10} represents minimum of 5 characters and maximum of 10 characters
final String SPECIAL_CHAR;
if (SPECIAL_CHAR_NEEDED==true) SPECIAL_CHAR= "(?=.*[@#$%^&+=])"; //(?=.*[@#$%^&+=]) a special character must occur at least once
else SPECIAL_CHAR="";
//_________________________
//Pattern
//String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}";
final String PATTERN = ONE_DIGIT + LOWER_CASE + UPPER_CASE + SPECIAL_CHAR + NO_SPACE + MIN_MAX_CHAR;
//_________________________
result = PASSWORD_Arg.matches(PATTERN);
//_________________________
}
} catch (Exception ex) {
result=false;
}
return result;
}