1. 概要

このクイックチュートリアルでは、文字列にJava の大文字、小文字、数字、または特殊文字のそれぞれが少なくとも1つ含まれているかどうかをチェックする方法を説明します。

2. 正規表現の使用

チェックを実行する方法の1つは、正規表現を使用することです。 正規表現に慣れるために、この記事をチェックしてください。

まず、必要な文字グループごとに正規表現を定義しましょう。 正規表現は固定されているため、実行のたびに評価する必要はありません。したがって、正規表現をコンパイルしてから比較します

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(".*[`~!@#$%^&*()\\-_=+\\\\|\\[{\\]};:'\",<.>/?].*");
}

また、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)" +
    "(?=.*?[`~!@#$%^&*()\\-_=+\\\\|\\[{\\]};:'\",<.>/?]).*$";

そして、それをコンパイルして比較します。

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

正規表現に関して指摘すべきことがいくつかあります。

最初に、文字のすべてのグループにポジティブ先読み(?= X)を使用しました。 つまり、一致させるために、文字列の先頭( ^ でマーク)の後に X が見つかると予想されますが、[の末尾には移動したくないということです。 X165X] X ではなく、行の先頭に留まりたいと考えています。

もう1つの注意点は、今回は文字グループに[AZ]または[az]を使用せず、 \ p{Lu}および[代わりにX132X]\p{Ll}。 これらは、英語だけでなく、あらゆる言語のあらゆる種類の文字(この場合はそれぞれ大文字と小文字)に一致します。

3. コアJavaの使用

正規表現を使用したくない場合に、同じチェックを実行する方法を見てみましょう。 CharacterクラスとStringクラスとそれらのメソッドを利用して、必要なすべての文字が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;
}

ここでいくつか注意する必要があります。 基本的な考え方は、 String を繰り返し処理し、その文字が必要なタイプであるかどうかを確認することです。 Character クラスを使用すると、特定の文字が数字、大文字、小文字のいずれであるかを簡単に確認できます。

残念ながら、特殊な文字の1つを扱っているかどうかを教えてくれる同様の方法はありません。 つまり、別のアプローチを取る必要があるということです。

必要なすべての特殊文字を含むStringを作成し、特定の文字が含まれているかどうかを確認しました。

4. 結論

この簡単な記事では、Stringに必要な文字が含まれているかどうかを確認する方法を示しました。 最初のシナリオでは正規表現を使用し、2番目のシナリオではコアJavaクラスを利用しました。

いつものように、完全なソースコードはGitHubにあります。