0Pricing
Java Academy · レッスン

Pattern と Matcher による正規表現

Java の正規表現を使って、メールアドレスを検証し、部分文字列を抽出し、パターンを置換します。

「Pattern と Matcher による正規表現」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。

PatternとMatcherによる正規表現

Javaのjava.util.regexパッケージは、強力なテキストの照合、検証、抽出、置換のためにPatternとMatcherを提供します。

正規表現を使う理由

正規表現(regex)は、テキストを照合するためのパターンです。Javaでは、メールアドレスや電話番号の検証、ログからのデータ抽出、構造化されたテキストの解析などに使用されます。

import java.util.regex.*;

// Is this a valid email?
String email = "alice@example.com";
boolean valid = email.matches("[a-zA-Z0-9._%+\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,}");
System.out.println(valid); // true

// Extract version numbers from a string
String log = "App v1.2.3 deployed; api v2.0.0 started";
Pattern p = Pattern.compile("v(\\d+\\.\\d+\\.\\d+)");
Matcher m = p.matcher(log);
while (m.find()) System.out.println(m.group(1));
// 1.2.3 
// 2.0.0

正規表現の構文の基礎

主な正規表現のメタ文字:

  • . — 任意の文字
  • \d — 数字、\w — 単語文字、\s — 空白文字
  • * — 0回以上、+ — 1回以上、? — 0回または1回
  • {n,m} — n回以上m回以下
  • ^/$ — 行の先頭/末尾
  • [abc] — 文字クラス
// In Java strings, backslash must be doubled: \d = "\\d"
Pattern digit   = Pattern.compile("\\d+");      // one or more digits
Pattern word    = Pattern.compile("\\w{3,20}");  // 3-20 word chars
Pattern space   = Pattern.compile("\\s+");       // whitespace
Pattern phone   = Pattern.compile("\\d{3}-\\d{3}-\\d{4}"); // 555-867-5309

System.out.println(digit.matcher("42").matches());       // true
System.out.println(phone.matcher("555-867-5309").matches()); // true

Pattern.compileとMatcher

パターンを一度コンパイルして、複数の入力でMatcherを再利用すると、繰り返し検証する場合にString.matches()を使うより効率的です。

import java.util.regex.*;

Pattern emailPattern = Pattern.compile(
    "^[a-zA-Z0-9._%+\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,6}$"
);

String[] emails = {"alice@example.com", "bad@", "test.user@co.uk", "no-at-sign"};
for (String e : emails) {
    Matcher m = emailPattern.matcher(e);
    System.out.println(e + " -> " + (m.matches() ? "valid" : "invalid"));
}

find()とmatches()の違い

matches()は文字列全体を検証します。find()は文字列内で次に一致する箇所を検索します。検索にはfindを、完全な検証にはmatchesを使用してください。

import java.util.regex.*;

Pattern price = Pattern.compile("\\d+\\.\\d{2}");

String invoice = "Total: 129.99, Tax: 10.40, Shipping: 5.00";
Matcher m = invoice.matcher(invoice);

// find() locates all matches
while (m.find()) {
    System.out.println("Found: " + m.group() + " at " + m.start());
}
// Found: 129.99 at 7
// Found: 10.40 at 20
// Found: 5.00 at 34

キャプチャグループ

括弧によってキャプチャグループを作成します。group(n)を使って、一致した部分文字列を抽出できます。

import java.util.regex.*;

Pattern date = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
Matcher m = date.matcher("Deployed on 2024-06-15 and 2024-07-01");

while (m.find()) {
    String year  = m.group(1);
    String month = m.group(2);
    String day   = m.group(3);
    System.out.println(year + "/" + month + "/" + day);
}
// 2024/06/15
// 2024/07/01

名前付きグループ

名前付きグループ(?<name>...)を使うと、キャプチャグループをより読みやすくし、名前でアクセスできます。

import java.util.regex.*;

Pattern log = Pattern.compile(
    "(?<timestamp>\\d{4}-\\d{2}-\\d{2}) (?<level>[A-Z]+) (?<message>.+)"
);

String line = "2024-06-15 ERROR Database connection failed";
Matcher m = log.matcher(line);

if (m.matches()) {
    System.out.println("Time: "    + m.group("timestamp"));
    System.out.println("Level: "   + m.group("level"));
    System.out.println("Message: " + m.group("message"));
}
// Time: 2024-06-15
// Level: ERROR
// Message: Database connection failed

replaceAllとreplaceFirst

パターンに基づく置換では、すべての出現箇所を置換することも、最初の1箇所だけを置換することもできます。

import java.util.regex.*;

String text = "Call us at 123-456-7890 or 098-765-4321";

// Mask phone numbers for privacy logs
String masked = text.replaceAll("\\d{3}-\\d{3}-\\d{4}", "XXX-XXX-XXXX");
System.out.println(masked);
// Call us at XXX-XXX-XXXX or XXX-XXX-XXXX

// Replace multiple whitespace with single space
String cleaned = "too   many   spaces".replaceAll("\\s+", " ");
System.out.println(cleaned); // too many spaces

正規表現でのsplit()

String.split()は正規表現を受け取ります。複数の区切り文字や複雑な区切りで分割する場合に使用します。

// Split on comma with optional spaces
String csv = "Alice, Bob,  Charlie,Diana";
String[] names = csv.split("\\s*,\\s*");
for (String name : names) System.out.println("'" + name + "'");
// 'Alice' 'Bob' 'Charlie' 'Diana'

// Split on any whitespace
String words = "one  two\tthree  four";
String[] parts = words.split("\\s+");
System.out.println(parts.length); // 4

// Limit splits
String line = "key=value=extra";
String[] kv = line.split("=", 2); // [key, value=extra]

Patternのフラグ

フラグによって正規表現の動作を変更できます:CASE_INSENSITIVE、MULTILINE、DOTALL。

import java.util.regex.*;

// Case-insensitive match
Pattern p = Pattern.compile("hello", Pattern.CASE_INSENSITIVE);
System.out.println(p.matcher("HELLO World").find()); // true

// MULTILINE: ^ and $ match line boundaries
Pattern multi = Pattern.compile("^ERROR", Pattern.MULTILINE);
String logs = "INFO start\nERROR crash\nINFO end";
Matcher m = multi.matcher(logs);
int count = 0;
while (m.find()) count++;
System.out.println("ERROR lines: " + count); // 1

実践:ログパーサー

名前付きグループを使って、Apache形式のアクセスログ行を解析します。

import java.util.regex.*;

Pattern accessLog = Pattern.compile(
    "(?<ip>[\\d.]+) - - \\[(?<time>[^\\]]+)\\] " +
    "\"(?<method>[A-Z]+) (?<path>[^ ]+)[^\"]*\" " +
    "(?<status>\\d{3}) (?<bytes>\\d+)"
);

String line = "192.168.1.1 - - [27/May/2024:10:30:00 +0000] \"GET /api/products HTTP/1.1\" 200 1024";
Matcher m = accessLog.matcher(line);
if (m.matches()) {
    System.out.println("IP: "     + m.group("ip"));
    System.out.println("Method: " + m.group("method"));
    System.out.println("Status: " + m.group("status"));
}

確認問題

Matcherにおけるmatches()とfind()の違いは何ですか。

まとめ:PatternとMatcherによる正規表現

要点:

  • Pattern.compile()は正規表現をコンパイルし、Matcherは文字列に対して検証します
  • matches()は文字列全体を検証し、find()は出現箇所を検索します
  • キャプチャグループ()は部分文字列を抽出し、group(n)またはgroup("name")でアクセスします
  • 名前付きグループ(?<name>...)によって、パターンが読みやすくなります
  • replaceAll()とsplit()は正規表現パターンを受け取り、柔軟なテキスト操作を可能にします
  • Pattern.CASE_INSENSITIVE、MULTILINE、DOTALLフラグを使って照合の動作を変更します

よくある質問

「Pattern と Matcher による正規表現」レッスンは無料ですか?

はい。「Pattern と Matcher による正規表現」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。

「Pattern と Matcher による正規表現」で何を学びますか?

Java の正規表現を使って、メールアドレスを検証し、部分文字列を抽出し、パターンを置換します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Java Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「Pattern と Matcher による正規表現」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJava Academyレッスンでコードを書いて実行できますか?

はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. String の不変性と String Pool
  2. 効率的な連結のための StringBuilder
  3. テキストブロックと String.format
  4. Pattern と Matcher による正規表現
← Java Academyに戻る