【问题标题】:Regular Expression in JAVA in making a passwordJAVA中的正则表达式制作密码
【发布时间】:2021-09-15 15:37:27
【问题描述】:

我有一个问题。我的目标是设置密码;密码必须由两个小写字母和 0-9 的 8 位数字组成。我已经使用正则表达式为此编写了一个代码,但问题是它超过了密码必须为 10 的总数,但我这里的代码实际上并不匹配。

这是我的代码:

System.out.print("Password: ");
        Scanner pass=new Scanner(System.in);
        String password=pass.next();
        String password_regex="(?=.*[0-9])(?=.*[a-z])(?=\\S+$).{8,}";
        boolean password_result=password.matches(password_regex);
        
        if(password_result){

【问题讨论】:

  • 为什么必须在一个正则表达式中完成所有操作?有很多更清洁的方法可以做到这一点。喜欢password.codePoints().filter(Character::isLetter).count() == 2 && password.codePoints().filter(Character::isDigit).count() == 8
  • 我真的很抱歉,这是我认为我可以做到但失败的一种方式。真的很抱歉......使用过滤器可以帮助我解决这个问题吗?
  • 无需道歉。我只是想建议正则表达式不是检查所需字符是否存在的唯一方法。我的建议使用a stream of the password’s characters,您可以过滤 IntStream。然后count() 将仅返回通过过滤器的字符数。

标签: java regex passwords


【解决方案1】:

正则表达式是重量级的,难以阅读。高度复杂的容易出错——编译器无法捕捉到的错误。您现在可能理解了正则表达式,但是当您在六个月后回到代码中时,您会理解它吗?其他人会理解吗?

除非您有特定要求只使用一个正则表达式进行整个检查,否则有比正则表达式更好的选择。你可以自己检查字符:

boolean hasTwoLetters =
    (password.codePoints().filter(Character::isLetter).count() == 2);
boolean hasEightDigits =
    (password.codePoints().filter(Character::isDigit).count() == 8);

boolean passwordValid = hasTwoLetters && hasEightDigits;

仅仅因为它看起来比单个正则表达式匹配更长并不意味着它会花费更长的时间。正则表达式引擎是复杂的库,内部包含大量代码。这种方法只是一次查看一个密码字符并计算它们。

有关详细信息,请参阅:

【讨论】:

    【解决方案2】:

    您可以仅在数字之间断言 2 个小写字符 a-z,然后匹配 a-z 或一个数字 10 次。

    ^(?=\d*[a-z]\d*[a-z]\d*$)[a-z\d]{10}$
    

    模式匹配:

    • ^ 字符串开始
    • (?=\d*[a-z]\d*[a-z]\d*$) 正向前瞻,在可选数字之间断言 2 个字符 a-z
    • [a-z\d]{10} 重复 10 次匹配字符 a-z 或数字
    • $字符串结束

    Regex demo

    在带有双转义反斜杠的 Java 中

    String regex = "^(?=\\d*[a-z]\\d*[a-z]\\d*$)[a-z\\d]{10}$";
    

    【讨论】:

    • 我不会使用正则表达式来解决这个问题;我认为 RE 被过度用作“我必须用一个表达式解决”的方法。你也许可以用一个简单的 RE 完成一半的工作,比如 [a-z0-9]{10,}(我的语法可能有点偏离),但我会留下“两个字母”进行明确检查。
    • @iggy 随时发布您的解决方案 :-)
    • @iggy 这一切都取决于用例。无论如何,这个建议的正则表达式是高效、快速和安全的,所以没有问题。也很清楚。
    • 嗨,我的目标输出是有效密码是 4ac5478959,其中两个小写字符位于数字之间。它以数字开头,无论字符的位置如何,只要它位于数字之间。感谢您提供我可以尝试的信息
    • @user16376117 如果字符必须在数字之间 ^(?=\d+[a-z]\d*[a-z]\d+$)[a-z\d]{10}$ regex101.com/r/PzO7iG/1
    猜你喜欢
    • 2012-05-02
    • 2023-02-03
    • 2018-09-30
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    相关资源
    最近更新 更多