1. Overview
1.概述
In this quick tutorial, we’ll illustrate how we can check if a String is containing at least one of each of the following: uppercase letter, lowercase letter, digit or special character in Java.
在这个快速教程中,我们将说明如何在Java中检查一个字符串是否包含以下各项中的至少一个:大写字母、小写字母、数字或特殊字符。
2. Using Regular Expressions
2.使用正则表达式
One of the ways to perform our check is by using regular expressions. To get familiar with regular expressions, please check out this article.
我们进行检查的方法之一是使用正则表达式。要熟悉正则表达式,请查看这篇文章。
First of all, let’s define the regular expression for each of the required character groups. Since regular expressions are fixed, there is no need to evaluate them at each run, so we’ll compile them before we compare against them:
首先,让我们为每个需要的字符组定义正则表达式。由于正则表达式是固定的,因此没有必要在每次运行时对其进行评估,所以我们将在与它们进行比较之前对其进行编译。
private static final Pattern[] inputRegexes = new Pattern[4];
static {
inputRegexes[0] = Pattern.compile(".*[A-Z].*");
inputRegexes[1] = Pattern.compile(".*[a-z].*");
inputRegexes[2] = Pattern.compile(".*\\d.*");
inputRegexes[3] = Pattern.compile(".*[`~!@#$%^&*()\\-_=+\\\\|\\[{\\]};:'\",<.>/?].*");
}
Also, we should create a simple method that we’re going to use to test if our String matches the conditions:
另外,我们应该创建一个简单的方法,用来测试我们的String是否符合条件。
private static boolean isMatchingRegex(String input) {
boolean inputMatches = true;
for (Pattern inputRegex : inputRegexes) {
if (!inputRegex.matcher(input).matches()) {
inputMatches = false;
}
}
return inputMatches;
}
2.1. Single Regular Expression
2.1.单一正则表达式
The previous example is pretty readable and allows us to use only some of the patterns easily if necessary. But, in a case where we care only about fulfilling all of the conditions, it is much more efficient to use a single regular expression.
前面的例子是相当可读的,并且允许我们在必要时只轻松使用一些模式。但是,在我们只关心满足所有条件的情况下,使用单一的正则表达式会更有效率。
That way we wouldn’t need a static block to initialize and compile all of our multiple expressions. Also, there would be no need to iterate over all of them and find which matches and which don’t.
这样,我们就不需要一个静态块来初始化和编译我们所有的多重表达式。另外,也不需要对所有的表达式进行迭代,找出哪些匹配,哪些不匹配。
All we need to do is to declare our regex:
我们所要做的就是声明我们的regex。
String regex = "^(?=.*?\\p{Lu})(?=.*?\\p{Ll})(?=.*?\\d)" +
"(?=.*?[`~!@#$%^&*()\\-_=+\\\\|\\[{\\]};:'\",<.>/?]).*$";
And then compile and compare it:
然后再进行编译和比较。
@Test
public void givenSingleRegex_whenMatchingCorrectString_thenMatches() {
String validInput = "Ab3;";
assertTrue(Pattern.compile(regex).matcher(validInput).matches());
}
There are a few things we should point out regarding our regular expression.
关于我们的正则表达式,有几件事我们应该指出来。
First, we’ve used positive lookahead (?=X) for every group of characters. That means that we expect X to be found after the beginning of the String (marked with ^) in order to match, but we don’t want to go to the end of X, rather we want to stay at the beginning of the line.
首先,我们对每一组字符都使用了正向查找(?=X)。这意味着我们希望X在字符串的开头(用^标记)之后被找到,以便进行匹配,但我们不想去找X的结尾,而是想停留在行的开头。
Another thing to notice is that this time we didn’t use [A-Z] or [a-z] for letter groups, but \p{Lu} and \p{Ll} instead. These will match any kind of letter (in our case, uppercase and lowercase respectively) from any language, not only English.
另外要注意的是,这次我们没有使用[A-Z]或[a-z]作为字母组,而是用p{Lu}和p{Ll}代替。这些将匹配任何语言的任何种类的字母(在我们的例子中,分别是大写和小写),而不仅仅是英语。
3. Using Core Java
3.使用Core Java
Let’s now see how we can perform the same check if we don’t want to use regular expressions. We’ll take advantage of Character and String classes and their methods to check if all required characters are present in our String:
现在让我们看看,如果我们不想使用正则表达式,我们如何执行同样的检查。我们将利用字符和字符串类及其方法来检查所有需要的字符是否存在于我们的字符串中。
private static boolean checkString(String input) {
String specialChars = "~`!@#$%^&*()-_=+\\|[{]};:'\",<.>/?";
char currentCharacter;
boolean numberPresent = false;
boolean upperCasePresent = false;
boolean lowerCasePresent = false;
boolean specialCharacterPresent = false;
for (int i = 0; i < input.length(); i++) {
currentCharacter = input.charAt(i);
if (Character.isDigit(currentCharacter)) {
numberPresent = true;
} else if (Character.isUpperCase(currentCharacter)) {
upperCasePresent = true;
} else if (Character.isLowerCase(currentCharacter)) {
lowerCasePresent = true;
} else if (specialChars.contains(String.valueOf(currentCharacter))) {
specialCharacterPresent = true;
}
}
return
numberPresent && upperCasePresent && lowerCasePresent && specialCharacterPresent;
}
We should note a few things here. Basic idea is that we iterate through our String and check if its characters are of required types. By using Character class, we can easily check if a certain character is a digit, an uppercase or a lowercase character.
我们应该在这里注意几件事。基本的想法是,我们遍历我们的String,并检查其字符是否为所需类型。通过使用Character类,我们可以轻松地检查某个字符是否是数字、大写或小写字符。
Unfortunately, there is no similar method that would tell us if we’re dealing with one of the special characters. So, it means that we need to take another approach.
不幸的是,没有类似的方法可以告诉我们是否在处理其中的一个特殊字符。因此,这意味着我们需要采取另一种方法。
We’ve created a String containing all special characters we need and then checked if it contains our specific character.
我们已经创建了一个包含所有我们需要的特殊字符的String,然后检查它是否包含我们的特定字符。
4. Conclusion
4.总结
In this quick article, we’ve shown how to check if a String contains required characters. In the first scenario, we used regular expressions while in the second we took advantage of core Java classes.
在这篇快速文章中,我们展示了如何检查一个String是否包含必要的字符。在第一种情况下,我们使用了正则表达式,而在第二种情况下,我们利用了核心Java类的优势。
As usual, complete source code can be found over on GitHub.
像往常一样,完整的源代码可以在GitHub上找到超过。