Java 通过正则表达式进行密码验证

Java 通过正则表达式进行密码验证,java,regex,Java,Regex,但当我像passW@ord45。意思是我不应该遵循这里写的正则表达式顺序模式 以下是下文给出的条件: 编写函数布尔值isValidPassword(字符串密码)如果密码满足以下条件,则该密码有效: 密码长度必须大于10(不计算) 空格) 密码必须至少包含一个大写字母和一个小字母 密码必须至少包含2位数字,如果没有2位数字,请参阅下一个条件 密码必须至少包含给定集合中的一个特殊字符-{$,@, _,-,,/} 您可以使用@davide comment中链接的方法,因此基本上: System.out

但当我像
passW@ord45
。意思是我不应该遵循这里写的正则表达式顺序模式

以下是下文给出的条件:

编写函数
布尔值isValidPassword(字符串密码)
如果密码满足以下条件,则该密码有效:

  • 密码长度必须大于10(不计算) 空格)
  • 密码必须至少包含一个大写字母和一个小字母
  • 密码必须至少包含2位数字,如果没有2位数字,请参阅下一个条件
  • 密码必须至少包含给定集合中的一个特殊字符-{$,@, _,-,,/}

  • 您可以使用@davide comment中链接的方法,因此基本上:

    System.out.println(Pattern.matches("[A-Z]{1,}[a-z]{1,}[0-9]{2,}[@#$%]+[ ]*", "DEFabc45$  "));
    
    但是,在任何地方使用
    *
    都会产生大量回溯(特别是
    *[0-9].[0-9]
    ),因此防止这种情况的方法是更明确的:

    (?=(?: *\\S){10})(?=.*[a-z])(?=.*[A-Z])(?=.*[$@_./-]|.*[0-9].*[0-9])
    
    关于这两种模式中使用的功能:

    \\S
    是一个速记字符类:所有这些字符都不是空白字符

    (?=…)
    是一种称为lookahead的零宽度断言(一种测试),后面是means。因此,您可以使用它从相同位置测试多个断言,如下所示:
    (?=…)(?=…)(?=…)(?=…)
    ,因为字符不会被使用

    *请注意,在第二种模式中,我选择不使用lookahead,因为没有更多的规则,所以是否使用字符并不重要

    因此,每个前瞻都包含一条规则:

    规则1:至少10个非空格字符

    (?=(?: *\\S){10,})(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])[^$@_./0-9-]*+(?:[$@_./-]|[0-9][^0-9]*[0-9])
    
    规则2a:小写字母

    (?=
        (?: *\\S){10}  # a group with optional spaces and one non space character
                       # the group is repeated 10 times, so there are at least
                       # 10 characters that are not a space
    )
    
    规则2B:大写字母(与2a相同,但带有
    A-Z

    规则3和4组合在一个子模式中,该子模式不在前瞻模式中,如下所述:

    (?=
        [^a-z]*    # zero or more characters that are not a lowercase letter
        [a-z]      # until a lowercase letter
    )
    

    您可以将这些模式与
    lookingAt
    一起使用,因为不需要在末尾锚定它们(根据您的需求)或者使用
    匹配
    ,但您需要在字符串末尾添加
    *

    这可能有助于Regex在这里是错误的工具-尽管您可能能够编写需求,但它将导致非常复杂的表达式。这几乎肯定是不可能理解的,因此,当你稍后再来讨论它时,它是无法维护的。使用Java中一些简单的代码语句和可读性更好的方法来解决这个问题。通常我都支持regex,但一旦你进入“如果不是这样的话”的逻辑,regex可能就不是办法了。@Srb1313711:不要假设,学习、测试自己、分析情况是唯一不重复的方法“主流论断”。@Casimirithippolyte我没有假设任何事情,我甚至没有说这是不可能的,我所说的是可能有更好的方法来实现这一点“这几乎肯定是不可能理解的,因此,当你稍后再来讨论它时,它会得到维护“我认为你很好地说明了我的观点:D@Paolo当前位置我们可以把学习阅读比作:当你识别单词和惯用表达、结构时,你就能立即理解句子的意思。不能理解一个模式(在这里是如此基本和众所周知)是因为缺乏技能。但如果掌握了这项技能,重写或修改这样的模式需要5分钟,就像其他任何事情一样。我认为这个解决方案是无效的。条件是:“不计算空格”。而不是:“不能包含空格”。我认为最好将regexp where appropitate与“普通”检查和方法调用(如
    .replace(“,”).length()>10
    等)混合使用@UniversE:No,这里考虑了空格:
    (?:*\\S){10}
    ,量词
    *
    使空格成为可选的,因此
    {10}
    将重复非空格字符10次。请注意,更严格地说,您可以编写
    (?:\\s*\\s){10}
    (但通常很难在密码字段中添加制表符或换行符,但谁知道呢?)。看这里:@casimirithippolyte哦,好吧-现在我明白了。。。您捕获一个字符和任何前面的空格,并将其作为一个。所以
    \uuuuuuuuuuuuuuuu1 | uuuuu2 | uuuuuu3 | uuuuuuuuu4 |
    等等。。(其中u是此处的空白)
    [^$@_./0-9-]*+          # all that is not a digit or a special character
                            # Note: I have added a possessive quantifier make the whole
                            # pattern to fail faster if the next group fails 
    (?: # two possibilities:
        [$@_./-]            # a special character
      |                  # OR
        [0-9][^0-9]*[0-9]   # two digits: a digit, other characters, an other digit 
    )