0

我已经搜索了该站点,但没有找到我正在寻找的确切内容。密码标准:

  1. 必须为 6 个字符,最多 50 个字符
  2. 必须包含 1 个字母字符
  3. 必须包含 1 个数字或特殊字符

这是我在java中拥有的:

public static Pattern p = Pattern.compile(
 "((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])|(?=.*[\\d~!@#$%^&*\\(\\)_+\\{\\}\\[\\]\\?<>|_]).{6,50})"
);

问题是密码 1234567 匹配(它是有效的)它不应该匹配。

任何帮助都会很棒。

4

6 回答 6

5

我不会尝试使用单个正则表达式来做到这一点。正则表达式在变得冗长而复杂时往往表现不佳。

boolean valid(String password){
    return password != null &&
    password.length() >= 6 &&
    password.length() <= 50 &&
    password.matches(".*[A-Za-z].*") &&
    password.matches(".*[0-9\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)_+\\{\\}\\[\\]\\?<>|_].*");
}
于 2013-05-13T17:51:31.857 回答
1

正则表达式只能匹配可以表示为确定性有限自动机的语言,即不需要内存的语言。由于您必须计算特殊字符和字母字符,这确实需要内存,因此您无法在 DFA 中执行此操作。您的规则很简单,尽管您可以只扫描密码、确定其长度并确保所需的字符可用。

于 2013-05-13T17:53:54.787 回答
1

我建议您将字符和长度验证分开:

boolean checkPassword(String password) {
    return password.length() >= 6 && password.length() <= 50 && Pattern.compile("\\d|\\w").matcher(password).find();
}
于 2013-05-13T17:55:20.400 回答
1

确保使用Matcher.matches()方法,该方法断言整个字符串与模式匹配。

您当前的正则表达式:

"((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])|(?=.*[\\d~!@#$%^&*\\(\\)_+\\{\\}\\[\\]\\?<>|_]).{6,50})"

方法:

  • 字符串必须至少包含一个数字(?=.*\\d)、一个小写英文字母(?=.*[a-z])和一个大写字符。(?=.*[A-Z])
  • |字符串必须至少包含 1 个字符,可以是数字或特殊字符(?=.*[\\d~!@#$%^&*\\(\\)_+\\{\\}\\[\\]\\?<>|_])
  • 上述任一条件均成立,并且字符串长度必须介于 6 到 50 个字符之间,并且不包含任何行分隔符。

正确的正则表达式是:

"(?=.*[a-zA-Z])(?=.*[\\d~!@#$%^&*()_+{}\\[\\]?<>|]).{6,50}"

这将检查:

  • 字符串必须包含一个英文字母字符(大写或小写)(?=.*[a-zA-Z]),以及一个可以是数字或特殊字符的字符(?=.*[\\d~!@#$%^&*()_+{}\\[\\]?<>|])
  • 该字符串必须介于 6 到 50 个字符之间,并且不包含任何行分隔符。

请注意,我删除了大多数字符的转义,除了[], 因为{}?()在字符类中失去了它们的特殊含义。

于 2013-05-13T18:05:08.533 回答
0

我建议拆分成单独的正则表达式

$re_numbers = "/[0-9]/";
$re_letters = "/[a-zA-Z]/";

它们都必须匹配,并且长度也单独测试。那时代码看起来很干净,更容易理解/更改。

于 2013-05-13T17:51:47.023 回答
0

对于这样一个简单的任务来说,这种方式太复杂了:

使用 String#length() 验证长度

password.length() >= 6 && password.length() <= 50

使用 Matcher#find() 验证每个组

Pattern alpha = Pattern.compile("[a-zA-Z]");
boolean hasAlpha = alpha.matcher(password).find();
Pattern digit = Pattern.compile("\d");
boolean hasDigit = digit.matcher(password).find();
Pattern special = Pattern.compile("[\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)_+\\{\\}\\[\\]\\?<>|_]");
boolean hasSpecial = special.matcher(password).find();
于 2013-05-13T17:51:55.357 回答