Java проверяет строку на наличие строчных/заглавных букв, специальных символов и цифр

Java проверяет строку на наличие строчных / заглавных букв, специальных символов и цифр

1. обзор

В этом кратком руководстве мы покажем, как можноcheck if a String is containing at least one of each of the following: uppercase letter, lowercase letter, digit or special character in Java.

2. Использование регулярных выражений

Один из способов выполнить нашу проверку - использовать регулярные выражения. Чтобы познакомиться с регулярными выражениями, ознакомьтесь сthis article.

Прежде всего, давайте определим регулярное выражение для каждой из требуемых групп символов. 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(".*[`[email protected]#$%^&*()\\-_=+\\\\|\\[{\\]};:'\",<.>/?].*");
}

Кроме того, мы должны создать простой метод, который мы собираемся использовать, чтобы проверить, соответствует ли наш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. Единственное регулярное выражение

Предыдущий пример довольно читабелен и позволяет нам легко использовать только некоторые шаблоны при необходимости. Но в случае, когда мы заботимся только о выполнении всех условий, гораздо эффективнее использовать одно регулярное выражение.

Таким образом, нам не понадобится статический блок для инициализации и компиляции всех наших множественных выражений. Кроме того, нет необходимости перебирать их все и находить, какие совпадения, а какие нет.

Все, что нам нужно сделать, это объявить наше регулярное выражение:

String regex = "^(?=.*?\\p{Lu})(?=.*?\\p{Ll})(?=.*?\\d)" +
    "(?=.*?[`[email protected]#$%^&*()\\-_=+\\\\|\\[{\\]};:'\",<.>/?]).*$";

А затем скомпилируйте и сравните это:

@Test
public void givenSingleRegex_whenMatchingCorrectString_thenMatches() {
    String validInput = "Ab3;";
    assertTrue(Pattern.compile(regex).matcher(validInput).matches());
}

Есть несколько вещей, которые мы должны указать относительно нашего регулярного выражения.

First, we’ve used positive lookahead (?=X) for every group of characters. Это означает, что мы ожидаем, чтоX будет найден после начала строки (отмеченной^) для сопоставления, но мы не хотим идти до концаX , скорее, мы хотим остаться в начале строки.

Следует также отметить, что на этот раз мы не использовали[A-Z] или[a-z] для групп букв, а вместо них использовали\p{Lu} и\p{Ll}. Они будут соответствовать любому виду букв (в нашем случае, прописным и строчным соответственно) на любом языке, а не только на английском.

3. Использование Core Java

Давайте теперь посмотрим, как мы можем выполнить ту же проверку, если мы не хотим использовать регулярные выражения. Мы воспользуемся преимуществами классовCharacter andString и их методов, чтобы проверить, присутствуют ли все необходимые символы в нашемString:

private static boolean checkString(String input) {
    String specialChars = "~`[email protected]#$%^&*()-_=+\\|[{]};:'\",<.>/?";
    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;
}

Мы должны отметить несколько вещей здесь. Основная идея состоит в том, что мы перебираем нашString и проверяем, относятся ли его символы к требуемым типам. Используя классCharacter, мы можем легко проверить, является ли определенный символ цифрой, символом верхнего или нижнего регистра.

К сожалению, не существует аналогичного метода, который бы сообщил нам, имеем ли мы дело с одним из специальных символов. Таким образом, это означает, что мы должны принять другой подход.

Мы создалиString, содержащий все необходимые нам специальные символы, а затем проверили, содержит ли он наш конкретный символ.

4. Заключение

В этой быстрой статье мы показали, как проверить, содержит лиString необходимые символы. In the first scenario, we used regular expressions while in the second we took advantage of core Java classes.

Как обычно, полный исходный код можно найтиover on GitHub.