如何检查字符串是否包含小写字母,大写字母,特殊字符和数字?

我一直在谷歌搜索,我没有找到我的问题的答案:

如何检查正则表达式字符串是否包含以下每个中的至少一个:

  • 大写字母

  • 小写字母

  • 数字

  • 特殊字符: ~!@#$%^&*()-_=+|[{]};:'",<.>/?`

所以我至少需要一个大写字母和至少一个小写字母,至少一个数字和至少一个特殊字符 .

我确定答案很简单,但我找不到 . 任何帮助是极大的赞赏 .

回答(6)

3 years ago

这可以在java中作为单个正则表达式执行,但我个人会使用类似Mark Rhodes提供的解决方案 . 随着规则变得更加复杂,这将变得荒谬快速(如果它还没有......) .

String regex = "^(?=.*?\\p{Lu})(?=.*?[\\p{L}&&[^\\p{Lu}]])(?=.*?\\d)" + 
               "(?=.*?[`~!@#$%^&*()\\-_=+\\\\\\|\\[{\\]};:'\",<.>/?]).*$"
  • ^这匹配字符串的开头 . 这不是必须的,但我觉得它有助于提高可读性和理解力 . 此外,使用它时,您通常可以大幅提升性能,几乎不会受到惩罚 .

  • (?= X)这称为正向前瞻 . 基本上我们所说的是“字符串的开头(^)必须跟随这个东西X才能匹配,但 DO NOT 将光标前进到X的末尾,保持在行的开头 . (这是"look ahead"部分 . )

  • . *?\ p 在行开头后吃字符,直到找到大写字母 . 如果没有找到大写字母,这将无法匹配 . 我们使用\ p 代替A-Z,因为我们不希望来自世界其他地方的人举手投诉我们的软件是如何由一个无知的美国人写的 .

  • 现在我们回到行的开头(我们回去因为我们使用了前瞻)并开始搜索 . *?[\ p && [^ \ p]]简写为“所有字母,减去首都“(因此匹配小写) .

  • . *?\ d . ?[`〜!@#$%^&()\ -_ = \\ | \ [{]};:'\“,< . > /?]重复数字和特殊字符列表 .

  • . * $匹配其他所有内容,直到行尾 . 我们这样做只是因为java中的'matches'方法的语义,看看整个字符串是否与正则表达式匹配 . 您可以离开这部分并使用Matcher#find()方法并获得相同的结果 .

  • The Owl is one of the best books ever written on any technical subject.阅读时间短而快 . 我不能推荐它 .

3 years ago

对于需要满足所有条件的测试,正则表达式不是很好 .

因此,最简单的答案是不要试图同时测试它们,而只是依次尝试四个类中的每一个 .

您的代码可能会慢一点,但它更容易阅读和维护,例如

public boolean isLegalPassword(String pass) {

     if (!pass.matches(".*[A-Z].*")) return false;

     if (!pass.matches(".*[a-z].*")) return false;

     if (!pass.matches(".*\\d.*")) return false;

     if (!pass.matches(".*[~!.......].*")) return false;

     return true;
}

EDIT 固定引号 - 一直在做太多该死的JS编程......

3 years ago

我同意@ Alnitak的答案是最容易阅读的,但是它每次运行时都必须评估正则表达式 . 由于正则表达式是固定的,因此编译它们然后与它们进行比较是有意义的 . 例如就像是:

private static final Pattern [] passwordRegexes = new Pattern[4];
    {
        passwordRegexes[0] = Pattern.compile(".*[A-Z].*");
        passwordRegexes[1] = Pattern.compile(".*[a-z].*");
        passwordRegexes[2] = Pattern.compile(".*\\d.*");
        passwordRegexes[3] = Pattern.compile(".*[~!].*");
    }
    public boolean isLegalPassword(String pass) {

        for(int i = 0; i < passwordRegexes.length; i++){
            if(!passwordRegexes[i].matcher(pass).matches())
                return false;
        }
        return true;
    }

在10个字符的密码上运行100,000次时,上面的代码速度是原来的两倍 . 虽然,我想现在你可以说这段代码更难阅读!没关系!

3 years ago

因为这些不会以任何特定顺序出现,所以每个必需的字符类都需要前瞻断言:

(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[~!@#$%\^&*()\-_=+\|\[{\]};:'",<.>/?])

(注意:因为反斜杠,插入符号,连字符和方括号在一个范围内可能是特殊的,如果它们出现在范围内,它们应该反斜杠转义,如第四个先行断言所示 . )

如果您的正则表达式变体支持 x 修饰符,则可以使用空格和注释使此构造更具可读性 . 在 java.util.regex 中,您可以执行以下操作:

(?x)         # extended syntax
(?=.*[A-Z])  # look ahead for at least one upper case
(?=.*[a-z])  # look ahead for at least one lower case
(?=.*[0-9])  # look ahead for at least one numeral
(?=.*[~!@#$%\^&*()\-_=+\|\[{\]};:'",<.>/?])
             # look ahead for at least one of the listed symbols

3 years ago

你在找character classes .

  • 大字母:[A-Z]

  • 小写字母:[a-z]

  • 数字:[0-9]或\ d

  • 特殊字符:[^ A-Za-z0-9](也就是说,不是其他任何一个, ^ 否定了这个类)


如果要测试'this'或'that',可以组合这些范围 . 例如,大字母或小字母将是 [A-Za-z] .

3 years ago

\w :用于匹配字母数字(字母可以大或小)
\W :用于匹配特殊字符

我认为这个RegEx对您有所帮助:

[\w|\W]+

这是一个很好的RegEx Simulator,您可以使用它来构建自己的RegEx .