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

Java 如何检查字符串是否包含小写字母、大写字母、特殊字符和数字?,java,regex,Java,Regex,我一直在谷歌上搜索,但我没有找到我的问题的答案: 如何使用正则表达式检查字符串是否至少包含以下各项之一: 大写字母 小写字母 数字 特殊字符:~`@$%^&*()-_=+\|[{]};:'“,/? 所以我需要至少一个大写字母,至少一个小写字母,至少一个数字,至少一个特殊字符 我相信答案很简单,但我找不到。非常感谢您的帮助。正则表达式对于需要满足所有几个条件的测试不是很好 因此,最简单的答案不是同时尝试和测试它们,而是依次尝试四个类中的每一个 您的代码可能会稍微慢一点,但更易于阅读和维护,例如

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

如何使用正则表达式检查字符串是否至少包含以下各项之一:

  • 大写字母
  • 小写字母
  • 数字
  • 特殊字符:
    ~`@$%^&*()-_=+\|[{]};:'“,/?
所以我需要至少一个大写字母,至少一个小写字母,至少一个数字,至少一个特殊字符


我相信答案很简单,但我找不到。非常感谢您的帮助。

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

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

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

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;
}
编辑固定引号-做了太多该死的JS编程…

你要找的

  • 大写字母:[A-Z]
  • 小写字母:[a-z]
  • 数字:[0-9]或\d
  • 特殊字符:[^A-Za-z0-9](即,不是任何其他字符,其中
    ^
    否定类)


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

,因为它们不会以任何特定顺序出现,因此需要对每个所需的字符类进行前瞻性断言:

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

我同意@Alnitak的答案是最容易阅读的,但它的缺点是每次运行时都必须对regex进行评估。因为regex是固定的,所以编译它们然后与它们进行比较是有意义的。 e、 g.类似于:

    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;
    }
private静态最终模式[]passwordregex=新模式[4];
{
passwordRegexes[0]=Pattern.compile(“%A-Z]”);
passwordRegexes[1]=Pattern.compile(“%a-z]”);
passwordRegexes[2]=Pattern.compile(“%d.*”);
passwordRegexes[3]=Pattern.compile(“.[~!]”);
}
公共布尔isLegalPassword(字符串传递){
for(int i=0;i

在10个字符的密码上运行100000次时,上述代码的速度是原来的两倍。不过,我想现在你可以说这段代码更难阅读!没关系!

这在java中作为一个正则表达式实现了你想要的功能,尽管我个人会使用类似Mark Rhodes提供的解决方案。这会很快变得可笑(如果还没有…)因为规则变得越来越复杂

String regex = "^(?=.*?\\p{Lu})(?=.*?[\\p{L}&&[^\\p{Lu}]])(?=.*?\\d)" + 
               "(?=.*?[`~!@#$%^&*()\\-_=+\\\\\\|\\[{\\]};:'\",<.>/?]).*$"
String regex=“^(?=.\\p{Lu})(?=.*?[\\p{L}&&[^\\p{Lu}])(?=.*?\\d)”+
"(?=.*?[`~!@#$%^&*()\\-_=+\\\\\\|\\[{\\]};:'\",/?]).*$"
  • ^这与字符串的开头相匹配。严格来说,这并不是必须的,但我发现它有助于可读性和理解。此外,在可能的情况下使用它通常会大大提高性能,而且几乎不会带来任何损失

  • (?=X)这称为正向前瞻。基本上,我们所说的是“字符串的开头(^)后面必须跟这个东西X才能匹配,但是不要将光标向前移动到X的末尾,保持在行的开头。(这是“前瞻”部分。)

  • .*?\p{Lu}在找到一个大写字母之前,请在行首后吃字符。如果没有找到大写字母,则无法匹配。我们使用\p{Lu}而不是a-Z,因为我们不希望世界其他地方的人举手抱怨我们的软件是由一个无知的美国人编写的

  • 现在我们返回到行的开头(我们返回,因为我们使用了lookahead)并开始搜索。*?[\p{L}&[^\p{Lu}]]缩写,表示“所有字母,减去大写字母”(因此匹配小写)

  • 对数字和特殊字符列表重复上述操作

  • .*$匹配所有其他内容直到行尾。我们之所以这样做,是因为java中“matches”方法的语义可以查看整个字符串是否与正则表达式匹配。您可以将这部分内容保留下来,然后使用Matcher#find()方法得到相同的结果

  • 而且它读起来又短又快,我推荐的还不够


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

    我认为这个正则表达式将对您有所帮助:

    [\w|\W]+
    

    这里有一个很好的例子,你可以用它来构建你自己的正则表达式。

    这证明了我的观点-我使用正则表达式已经有多少年了,而且从来没有使用过前瞻性断言,读起来很困难。有四个简单正则表达式的版本可以被任何人阅读。(+1)回答得好。请确保使用全局匹配(哪种情况最常见)@Alnitak我现在演示了扩展语法的使用,它使表达式易于阅读,并且得到OP语言的支持。我倾向于在示例中避免使用它,只是为了使我的表达式在没有扩展语法的正则表达式实现中更普遍地有用。Tim是对的。另外,您如何应用正则表达式?如果您使用在
    matches()
    方法中,您需要使用
    *
    或其他东西来完成正则表达式,使其消耗整个字符串。原始问题不提供上下文。例如,它没有说正则表达式将“按原样”交给
    matches()
    。OP可能希望使用
    matcher()的解决方案
    ,或者作为更大正则表达式的一部分
    [\w|\W]+