【プログラミングしてみよう29】Javaの正規表現入門(Regex)で文字列を自在に検索・検証する

Java

前回はSetを使って重複なしのデータを管理する方法を学びました。

今回は「正規表現(Regex)」について解説します。 正規表現を使うことで、「メールアドレスの形式かどうか確認したい」「電話番号だけを文字列から取り出したい」といった複雑な文字列の検索・検証・置換を、シンプルなパターンで表現できるようになります。

正規表現の基本

正規表現とは、文字列のパターンを表現するための記法です。Javaでは java.util.regex パッケージの PatternMatcher を使って正規表現を扱います。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

よく使うパターン記号は以下の通りです。

.       // 任意の1文字
*       // 直前の文字が0回以上繰り返す
+       // 直前の文字が1回以上繰り返す
?       // 直前の文字が0回または1回
{n}     // 直前の文字がn回繰り返す
{n,m}   // 直前の文字がn回以上m回以下繰り返す
[abc]   // a、b、cのいずれか1文字
[a-z]   // aからzのいずれか1文字
\d      // 数字(0〜9)
\w      // 英数字またはアンダースコア
\s      // 空白文字
^       // 文字列の先頭
$       // 文字列の末尾

サンプルコード(パターンマッチングと検証)

ファイル作成

「Java18」フォルダに RegexTest.java という名前でファイルを作成します

コード入力

以下のコードを入力します。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest {
    public static void main(String[] args) {
        // 郵便番号の検証(例: 123-4567)
        String zipPattern = "^\\d{3}-\\d{4}$";
        String[] zipCodes = {"123-4567", "12-3456", "1234-567", "abc-defg"};

        System.out.println("--- 郵便番号の検証 ---");
        for (String zip : zipCodes) {
            boolean isValid = zip.matches(zipPattern);
            System.out.println(zip + " : " + (isValid ? "正しい形式" : "不正な形式"));
        }

        // メールアドレスの検証
        String emailPattern = "^[\\w.+-]+@[\\w-]+\\.[a-zA-Z]{2,}$";
        String[] emails = {"user@example.com", "invalid-email", "test.user@mail.co.jp"};

        System.out.println("\n--- メールアドレスの検証 ---");
        for (String email : emails) {
            boolean isValid = email.matches(emailPattern);
            System.out.println(email + " : " + (isValid ? "正しい形式" : "不正な形式"));
        }

        // 電話番号の検証(例: 090-1234-5678 または 0312345678)
        String phonePattern = "^(\\d{2,4}-\\d{2,4}-\\d{4}|\\d{10,11})$";
        String[] phones = {"090-1234-5678", "0312345678", "123-45-6789"};

        System.out.println("\n--- 電話番号の検証 ---");
        for (String phone : phones) {
            boolean isValid = phone.matches(phonePattern);
            System.out.println(phone + " : " + (isValid ? "正しい形式" : "不正な形式"));
        }
    }
}

コンパイル

javac RegexTest.java

実行

java RegexTest

実行結果は次のようになります。

--- 郵便番号の検証 ---
123-4567 : 正しい形式
12-3456 : 不正な形式
1234-567 : 不正な形式
abc-defg : 不正な形式

--- メールアドレスの検証 ---
user@example.com : 正しい形式
invalid-email : 不正な形式
test.user@mail.co.jp : 不正な形式

--- 電話番号の検証 ---
090-1234-5678 : 正しい形式
0312345678 : 正しい形式
123-45-6789 : 正しい形式

サンプルコード(文字列の検索と置換)

ファイル作成

「Java18」フォルダに RegexFindTest.java という名前でファイルを作成します

コード入力

以下のコードを入力します。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexFindTest {
    public static void main(String[] args) {
        String text = "連絡先: 090-1234-5678、または 080-9876-5432 までお電話ください。";

        // 文字列から電話番号をすべて取り出す
        Pattern pattern = Pattern.compile("\\d{2,4}-\\d{2,4}-\\d{4}");
        Matcher matcher = pattern.matcher(text);

        System.out.println("--- 電話番号の抽出 ---");
        while (matcher.find()) {
            System.out.println("見つかりました: " + matcher.group());
        }

        // 文字列の置換
        String replaced = text.replaceAll("\\d{2,4}-\\d{2,4}-\\d{4}", "***-****-****");
        System.out.println("\n--- マスク後のテキスト ---");
        System.out.println(replaced);

        // 空白の正規化(複数の空白を1つにまとめる)
        String messy = "これは    空白が    多い    文章です。";
        String normalized = messy.replaceAll("\\s+", " ");
        System.out.println("\n--- 空白の正規化 ---");
        System.out.println("前: " + messy);
        System.out.println("後: " + normalized);
    }
}

コンパイル

javac RegexFindTest.java

実行

java RegexFindTest

実行結果は次のようになります。

--- 電話番号の抽出 ---
見つかりました: 090-1234-5678
見つかりました: 080-9876-5432

--- マスク後のテキスト ---
連絡先: ***-****-****、または ***-****-**** までお電話ください。

--- 空白の正規化 ---
前: これは    空白が    多い    文章です。
後: これは 空白が 多い 文章です。

コードの解説

str.matches(pattern) は文字列全体がパターンに一致するかどうかを確認します。^$ で文字列の先頭と末尾を指定することで、部分一致ではなく完全一致での検証ができます。

郵便番号パターン ^\\d{3}-\\d{4}$ では、\\d が数字1文字を、{3} が3回の繰り返しを表します。Javaの文字列では \\\ と書く必要があるため、正規表現の \d\\d と書く点に注意してください。

Pattern.compile() でパターンオブジェクトを作成し、pattern.matcher(text) で対象文字列に対するMatcherを取得します。matcher.find() は文字列の中にパターンに一致する部分があれば true を返し、次の find() 呼び出しではその次の一致箇所を探します。matcher.group() で一致した文字列を取り出せます。

replaceAll() は一致するすべての部分を置換します。電話番号をマスクする処理のように、個人情報を隠したい場面などでよく使われます。\\s+ は1つ以上の空白文字を表すパターンで、replaceAll("\\s+", " ") で複数の空白をまとめて1つの空白に置換できます。

まとめ

正規表現を使うことで、文字列の検証・検索・置換を柔軟なパターンで表現できます。matches() で完全一致の検証、PatternMatcher で文字列内の部分検索、replaceAll() でパターンに一致する部分の置換という3つの使い方を覚えておきましょう。\\d で数字、\\s で空白、+{n} で繰り返しを表すパターン記号も少しずつ慣れていくと、幅広い文字列処理に応用できます。入力値の検証やログの解析など、実際の開発でも頻繁に登場する技術ですので、ぜひ手を動かして試してみてください。

2026/07/08(水) ぱんまる

コメント

タイトルとURLをコピーしました