简体   繁体   English

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

[英]How to check whether a string contains lowercase letter, uppercase letter, special character and digit?

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. 任何帮助是极大的赞赏。

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, eg 您的代码可能是分数慢,但它会更容易阅读和维护,如

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编程......

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. 我同意@ Alnitak的答案是最容易阅读的,但是它每次运行时都必须评估正则表达式。 Since the regexs are fixed, it makes sense to compile them then compare against them. 由于正则表达式是固定的,因此编译它们然后与它们进行比较是有意义的。 eg Something like: 例如:

    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. 当使用10个字符的密码运行100,000次时,上述代码的速度是原来的两倍。 Although, I guess now you could say this code is harder to read! 虽然,我想现在你可以说这段代码更难读! Never mind! 没关系!

This does what you want in java as a single regex, although I would personally use something like the solution provided by Mark Rhodes. 这可以在java中作为单个正则表达式执行,但我个人会使用类似Mark Rhodes提供的解决方案。 This will get ridiculous quick (if it isn't already...) as the rules get more complicated. 随着规则变得更加复杂,这将很快变得荒谬(如果还没有......)。

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. (?= X )这被称为正向前瞻。 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的末尾,保持在行的开头。(那就是“向前看”部分。)

  3. .*?\\p{Lu} eat characters after the beginning of the line until you find a capital letter. 。*?\\ p {Lu}在行开头后吃字符,直到找到大写字母。 This will fail to match if no capital letter is found. 如果没有找到大写字母,这将无法匹配。 We use \\p{Lu} instead of AZ 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}代替AZ,因为我们不希望来自世界其他地方的人举手投诉我们的软件是如何由一个无知的美国人写的。

  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). 现在我们回到行的开头(我们回去因为我们使用了前瞻)并开始搜索。*?[\\ p {L} && [^ \\ p {Lu}]]简写为“所有字母,减去首都“(因此匹配小写)。

  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. 我们这样做只是因为java中'matches'方法的语义,看看整个字符串是否与正则表达式匹配。 You could leave this part of and use the Matcher#find() method and get the same result. 您可以离开这部分并使用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. 我不能推荐它。

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

This construct can be made considerably more readable using whitespace and comments, if your regex variant supports the x modifier. 如果您的正则表达式变体支持x修饰符,则可以使用空格和注释使此构造更具可读性。 In java.util.regex , you can do: 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

You're looking for character classes . 你正在寻找角色类

  • Big letter: [AZ] 大信:[AZ]
  • Small letter: [az] 小写字母:[az]
  • 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. 如果要测试“this”或“that”,可以组合这些范围。 For example, Big or Small letters would be [A-Za-z] . 例如,大字母或小字母将是[A-Za-z]

\\w : is used for matching alpha-numeric (alphabets can be either big or small) \\w :用于匹配字母数字(字母可以大或小)
\\W : is used for matching special characters \\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。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM