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

时间:2020-12-19 01:33:38

I've been Googling a lot and I didn't find an answer for my question:

我在谷歌上搜索了很多次,但是我没有找到我的问题的答案:

How can I check with a regular expression whether a string contains at least one of each of these:

如何用正则表达式检查字符串是否包含至少其中一个:

  • Uppercase letter
  • 大写字母
  • Lowercase letter
  • 小写字母
  • Digit
  • 数字
  • Special Character: ~`!@#$%^&*()-_=+\|[{]};:'",<.>/?
  • 特殊字符:~ ! @ # $ % ^ & *()_ = + \ | {]};:“”,<,> / ?

So I need at least a capital letter and at least a small letter and at least a digit and at least a special character.

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

I'm sure the answer is very simple, but I can't find it. Any help is greatly appreciated.

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

6 个解决方案

#1


12  

This does what you want in java as a single regex, although I would personally use something like the solution provided by Mark Rhodes. This will get ridiculous quick (if it isn't already...) as the rules get more complicated.

这在java中作为一个单独的regex实现了您想要的功能,尽管我个人会使用类似于Mark Rhodes提供的解决方案。随着规则变得越来越复杂,这将变得荒唐可笑(如果它还没有……)。

String regex = "^(?=.*?\\p{Lu})(?=.*?[\\p{L}&&[^\\p{Lu}]])(?=.*?\\d)" + 
               "(?=.*?[`~!@#$%^&*()\\-_=+\\\\\\|\\[{\\]};:'\",<.>/?]).*$"
  1. ^ This matches the beginning of the string. It's not strictly necessary for this to work, but I find it helps readability and understanding. Also, using it when you can often makes a big performance improvement and is almost never a penalty.

    ^匹配字符串的开始。这并不是严格意义上的工作,但我发现它有助于可读性和理解。此外,当您能够使用它时,通常会有很大的性能改进,而且几乎不会带来任何损失。

  2. (?=X) This is called a positive lookahead. Basically what we're saying is "The beginning of the string (^) must be followed by this thing X in order for a match, but DO NOT advance the cursor to the end of X, stay at the beginning of the line. (that's the "look ahead" part.)

    (?=X)这就是所谓的正向超前。基本上我们要说的是字符串的开始(^)必须遵循这个X为了一场比赛,但不要提前光标的X,呆在一行的开始处。(这是“向前看”的部分。)

  3. .*?\p{Lu} eat characters after the beginning of the line until you find a capital letter. This will fail to match if no capital letter is found. We use \p{Lu} instead of A-Z because we don't want people from other parts of the world to throw up their hands and complain about how our software was written by an ignorant American.

    . * ?在一行开始后吃几个字,直到你找到一个大写字母。如果没有找到大写字母,这将无法匹配。我们使用\p{Lu}而不是A-Z,因为我们不希望世界其他地方的人举手,抱怨我们的软件是由一个无知的美国人写的。

  4. Now we go back to the beginning of the line (we go back because we used lookahead) and start a search for .*?[\p{L}&&[^\p{Lu}]] shorthand for "all letters, minus the capitals" (hence matches lower case).

    现在我们返回到行的开头(我们返回因为我们使用了lookahead)并开始搜索。[\ p { L } & &[^ \ p {陆}]]简称“所有的信件,减去资本”(因此匹配小写)。

  5. .*?\d + .*?[`~!@#$%^&*()\-_=+\\\|\[{\]};:'\",<.>/?] repeat for digits and for your list of special characters.

    . * ?\ d + . * ?[' ~ ! @ # $ % ^ & *()\ _ = + \ \ \ | \[{ \]};:“\”,<,> / ?[英语背诵文选为数字和你的特殊字符列表重复。

  6. .*$ Match everything else until the end of the line. We do this just because of the semantics of the 'matches' methods in java that see if the entire string is a match for the regex. You could leave this part of and use the Matcher#find() method and get the same result.

    .*$匹配其他所有内容直到行尾。我们这样做是因为java中“match”方法的语义,它查看整个字符串是否与regex匹配。您可以保留这一部分并使用Matcher#find()方法,并获得相同的结果。

  7. The Owl is one of the best books ever written on any technical subject. And it's short and fast to read. I cannot recommend it enough.

    猫头鹰是有史以来写在任何技术主题上的最好的书之一。而且读起来又短又快。我再怎么推荐也不为过。

#2


34  

Regular expressions aren't very good for tests where you require all of several conditions to be met.

正则表达式不适用于需要满足所有条件的测试。

The simplest answer therefore is not to try and test them all at the same time, but just to try each of the four classes in turn.

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

Your code might be fractionally slower, but it'll be easier to read and maintain, e.g.

你的代码可能会稍微慢一点,但是它会更容易读和维护,例如。

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 fixed quote marks - been doing too much damned JS programming...

编辑固定的引号——做了太多该死的JS编程……

#3


12  

I agree that @Alnitak's answer is the easiest to read, however it suffers from the fact that it has to evaluate the regexs each time it's run. Since the regexs are fixed, it makes sense to compile them then compare against them. e.g. Something like:

我同意@Alnitak的答案是最容易阅读的,但是它的缺点是每次运行时都要对regexs进行评估。由于regexs是固定的,所以编译它们然后与它们进行比较是有意义的。例如像:

    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;
    }

When run 100,000 times on a 10 character password the above code was twice as fast. Although, I guess now you could say this code is harder to read! Never mind!

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

#4


7  

Because these will not appear in any particular order, you will need lookahead assertions for each required character class:

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

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

(NOTE: because backslash, caret, hyphen, and square brackets can be special inside a range, they should be backslash escaped if they appear in the range, as shown in the fourth lookahead assertion.)

(注意:由于反斜杠、插入符号、连字符和方括号在一个范围内是特殊的,如果它们出现在范围内,它们应该是反斜杠,如第四个lookahead断言所示。)

This construct can be made considerably more readable using whitespace and comments, if your regex variant supports the x modifier. In java.util.regex, you can do:

如果regex变体支持x修饰符,则可以使用空格和注释使该构造更具可读性。在java.util。正则表达式,可以做的事:

(?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

#5


-1  

You're looking for character classes.

你在寻找角色类。

  • Big letter: [A-Z]
  • 大信:[a - z]
  • Small letter: [a-z]
  • 小信:[a - z]
  • Digit: [0-9] or \d
  • 数字:[0 - 9]或\ d
  • Special character: [^A-Za-z0-9] (That is, not any of the others, where ^ negates the class)
  • 特殊字符:[^ A-Za-z0-9](也就是说,不是任何其他人,其中^否定类)

If you want to test for 'this' or 'that', you can combine those ranges. For example, Big or Small letters would be [A-Za-z].

如果您想测试“this”或“that”,您可以合并这些范围。例如,大小写字母都是[A-Za-z]。

#6


-1  

\w: is used for matching alpha-numeric (alphabets can be either big or small)
\W: is used for matching special characters

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

I think this RegEx will be helpful for you:

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

[\w|\W]+

Here's a good RegEx Simulator, you can use it for building your own RegEx.

这是一个很好的RegEx模拟器,您可以使用它构建自己的RegEx。

#1


12  

This does what you want in java as a single regex, although I would personally use something like the solution provided by Mark Rhodes. This will get ridiculous quick (if it isn't already...) as the rules get more complicated.

这在java中作为一个单独的regex实现了您想要的功能,尽管我个人会使用类似于Mark Rhodes提供的解决方案。随着规则变得越来越复杂,这将变得荒唐可笑(如果它还没有……)。

String regex = "^(?=.*?\\p{Lu})(?=.*?[\\p{L}&&[^\\p{Lu}]])(?=.*?\\d)" + 
               "(?=.*?[`~!@#$%^&*()\\-_=+\\\\\\|\\[{\\]};:'\",<.>/?]).*$"
  1. ^ This matches the beginning of the string. It's not strictly necessary for this to work, but I find it helps readability and understanding. Also, using it when you can often makes a big performance improvement and is almost never a penalty.

    ^匹配字符串的开始。这并不是严格意义上的工作,但我发现它有助于可读性和理解。此外,当您能够使用它时,通常会有很大的性能改进,而且几乎不会带来任何损失。

  2. (?=X) This is called a positive lookahead. Basically what we're saying is "The beginning of the string (^) must be followed by this thing X in order for a match, but DO NOT advance the cursor to the end of X, stay at the beginning of the line. (that's the "look ahead" part.)

    (?=X)这就是所谓的正向超前。基本上我们要说的是字符串的开始(^)必须遵循这个X为了一场比赛,但不要提前光标的X,呆在一行的开始处。(这是“向前看”的部分。)

  3. .*?\p{Lu} eat characters after the beginning of the line until you find a capital letter. This will fail to match if no capital letter is found. We use \p{Lu} instead of A-Z because we don't want people from other parts of the world to throw up their hands and complain about how our software was written by an ignorant American.

    . * ?在一行开始后吃几个字,直到你找到一个大写字母。如果没有找到大写字母,这将无法匹配。我们使用\p{Lu}而不是A-Z,因为我们不希望世界其他地方的人举手,抱怨我们的软件是由一个无知的美国人写的。

  4. Now we go back to the beginning of the line (we go back because we used lookahead) and start a search for .*?[\p{L}&&[^\p{Lu}]] shorthand for "all letters, minus the capitals" (hence matches lower case).

    现在我们返回到行的开头(我们返回因为我们使用了lookahead)并开始搜索。[\ p { L } & &[^ \ p {陆}]]简称“所有的信件,减去资本”(因此匹配小写)。

  5. .*?\d + .*?[`~!@#$%^&*()\-_=+\\\|\[{\]};:'\",<.>/?] repeat for digits and for your list of special characters.

    . * ?\ d + . * ?[' ~ ! @ # $ % ^ & *()\ _ = + \ \ \ | \[{ \]};:“\”,<,> / ?[英语背诵文选为数字和你的特殊字符列表重复。

  6. .*$ Match everything else until the end of the line. We do this just because of the semantics of the 'matches' methods in java that see if the entire string is a match for the regex. You could leave this part of and use the Matcher#find() method and get the same result.

    .*$匹配其他所有内容直到行尾。我们这样做是因为java中“match”方法的语义,它查看整个字符串是否与regex匹配。您可以保留这一部分并使用Matcher#find()方法,并获得相同的结果。

  7. The Owl is one of the best books ever written on any technical subject. And it's short and fast to read. I cannot recommend it enough.

    猫头鹰是有史以来写在任何技术主题上的最好的书之一。而且读起来又短又快。我再怎么推荐也不为过。

#2


34  

Regular expressions aren't very good for tests where you require all of several conditions to be met.

正则表达式不适用于需要满足所有条件的测试。

The simplest answer therefore is not to try and test them all at the same time, but just to try each of the four classes in turn.

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

Your code might be fractionally slower, but it'll be easier to read and maintain, e.g.

你的代码可能会稍微慢一点,但是它会更容易读和维护,例如。

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 fixed quote marks - been doing too much damned JS programming...

编辑固定的引号——做了太多该死的JS编程……

#3


12  

I agree that @Alnitak's answer is the easiest to read, however it suffers from the fact that it has to evaluate the regexs each time it's run. Since the regexs are fixed, it makes sense to compile them then compare against them. e.g. Something like:

我同意@Alnitak的答案是最容易阅读的,但是它的缺点是每次运行时都要对regexs进行评估。由于regexs是固定的,所以编译它们然后与它们进行比较是有意义的。例如像:

    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;
    }

When run 100,000 times on a 10 character password the above code was twice as fast. Although, I guess now you could say this code is harder to read! Never mind!

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

#4


7  

Because these will not appear in any particular order, you will need lookahead assertions for each required character class:

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

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

(NOTE: because backslash, caret, hyphen, and square brackets can be special inside a range, they should be backslash escaped if they appear in the range, as shown in the fourth lookahead assertion.)

(注意:由于反斜杠、插入符号、连字符和方括号在一个范围内是特殊的,如果它们出现在范围内,它们应该是反斜杠,如第四个lookahead断言所示。)

This construct can be made considerably more readable using whitespace and comments, if your regex variant supports the x modifier. In java.util.regex, you can do:

如果regex变体支持x修饰符,则可以使用空格和注释使该构造更具可读性。在java.util。正则表达式,可以做的事:

(?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

#5


-1  

You're looking for character classes.

你在寻找角色类。

  • Big letter: [A-Z]
  • 大信:[a - z]
  • Small letter: [a-z]
  • 小信:[a - z]
  • Digit: [0-9] or \d
  • 数字:[0 - 9]或\ d
  • Special character: [^A-Za-z0-9] (That is, not any of the others, where ^ negates the class)
  • 特殊字符:[^ A-Za-z0-9](也就是说,不是任何其他人,其中^否定类)

If you want to test for 'this' or 'that', you can combine those ranges. For example, Big or Small letters would be [A-Za-z].

如果您想测试“this”或“that”,您可以合并这些范围。例如,大小写字母都是[A-Za-z]。

#6


-1  

\w: is used for matching alpha-numeric (alphabets can be either big or small)
\W: is used for matching special characters

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

I think this RegEx will be helpful for you:

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

[\w|\W]+

Here's a good RegEx Simulator, you can use it for building your own RegEx.

这是一个很好的RegEx模拟器,您可以使用它构建自己的RegEx。