1. Обзор
В этом кратком руководстве мы проиллюстрируем, как мы можем проверить, содержит ли строка
хотя бы одно из следующего: заглавную букву, строчную букву, цифру или специальный символ в Java .
2. Использование регулярных выражений
Один из способов выполнить нашу проверку — использовать регулярные выражения. Чтобы ознакомиться с регулярными выражениями, ознакомьтесь с этой статьей .
Прежде всего, давайте определим регулярное выражение для каждой из необходимых групп символов. Поскольку регулярные выражения фиксированы, нет необходимости оценивать их при каждом запуске, поэтому мы скомпилируем их, прежде чем сравнивать с ними :
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(".*[`~!@#$%^&*()\\-_=+\\\\|\\[{\\]};:'\",<.>/?].*");
}
Кроме того, мы должны создать простой метод, который мы собираемся использовать для проверки соответствия нашей строки
условиям:
private static boolean isMatchingRegex(String input) {
boolean inputMatches = true;
for (Pattern inputRegex : inputRegexes) {
if (!inputRegex.matcher(input).matches()) {
inputMatches = false;
}
}
return inputMatches;
}
2.1. Одно регулярное выражение
Предыдущий пример довольно удобочитаем и позволяет нам легко использовать только некоторые шаблоны, если это необходимо. Но в случае, когда нас интересует только выполнение всех условий, гораздо эффективнее использовать одно регулярное выражение.
Таким образом, нам не понадобится статический блок для инициализации и компиляции всех наших множественных выражений. Кроме того, не было бы необходимости перебирать их все и находить, какие совпадают, а какие нет.
Все, что нам нужно сделать, это объявить наше регулярное выражение:
String regex = "^(?=.*?\\p{Lu})(?=.*?\\p{Ll})(?=.*?\\d)" +
"(?=.*?[`~!@#$%^&*()\\-_=+\\\\|\\[{\\]};:'\",<.>/?]).*$";
А затем скомпилируйте и сравните его:
@Test
public void givenSingleRegex_whenMatchingCorrectString_thenMatches() {
String validInput = "Ab3;";
assertTrue(Pattern.compile(regex).matcher(validInput).matches());
}
Есть несколько вещей, которые мы должны отметить в отношении нашего регулярного выражения.
Во- первых, мы использовали положительный просмотр вперед ( ?=X
) для каждой группы символов . Это означает, что мы ожидаем, что X
будет найден после начала строки (отмеченной ^
) для сопоставления, но мы не хотим идти в конец X
, а хотим остаться в начале строки .
Следует также отметить, что на этот раз мы использовали не [AZ]
или [az]
для групп букв, а вместо этого использовали \p{Lu}
и \p{Ll} .
Они будут соответствовать любому типу букв (в нашем случае прописных и строчных соответственно) на любом языке, а не только на английском.
3. Использование ядра Java
Давайте теперь посмотрим, как мы можем выполнить ту же проверку, если мы не хотим использовать регулярные выражения. Мы воспользуемся классами символов
и строк
и их методами, чтобы проверить, присутствуют ли все необходимые символы в нашей строке
:
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;
}
Мы должны отметить несколько вещей здесь. Основная идея заключается в том, что мы перебираем нашу строку
и проверяем, относятся ли ее символы к требуемым типам. Используя класс Character
, мы можем легко проверить, является ли определенный символ цифрой, символом верхнего или нижнего регистра.
К сожалению, нет аналогичного метода, который бы сказал нам, имеем ли мы дело с одним из спецсимволов. Значит, нам нужен другой подход.
Мы создали строку
, содержащую все необходимые нам специальные символы, а затем проверили, содержит ли она наш конкретный символ.
4. Вывод
В этой быстрой статье мы показали, как проверить, содержит ли строка
обязательные символы. В первом сценарии мы использовали регулярные выражения, а во втором — основные классы Java .
Как обычно, полный исходный код можно найти на GitHub .