Matcher は「正規表現パターンを文字列に当てていく実行役」
前回の Pattern の話とつなげると、役割分担はこうです。
Pattern
「正規表現(パターン)そのもの」を表す。何度も使い回せる“型”のような存在。
Matcher
「このパターンを、この文字列に当ててみよう」という“実行役”。
マッチング結果(どこに一致があったか、どんなグループが取れたか)も覚えてくれる。
流れとしては、
- 正規表現から Pattern を作る(コンパイルする)
- Pattern から Matcher を作る(どの文字列に当てるか決める)
- Matcher のメソッド(matches, find, group など)で結果を調べたり、置換したりする
という順番になります。
ここからは、この Matcher を「どう使うか」「どこでハマりやすいか」を、例をまじえて整理していきます。
基本の流れ:Pattern → Matcher → matches / find
全体がパターンに一致しているかを調べる(matches)
まずは一番シンプルな使い方から。
数字だけの文字列かどうかをチェックする例です。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class MatcherExample {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("\\d+"); // 1文字以上の数字
Matcher matcher = pattern.matcher("12345");
boolean result = matcher.matches();
System.out.println(result); // true
}
}
Javaここでのポイントは matches() が
文字列全体がパターンにマッチしているか
をチェックしている、という点です。
"12345" は「数字だけ」なので true。"abc123" なら false になります。
Matcher m = pattern.matcher("abc123");
System.out.println(m.matches()); // false
Java「入力値の形式チェック」のように、「全部がその形であってほしい」ときは matches() を使うのが基本です。
部分一致を探す(find)
今度は「文字列の中にパターンに合う部分があるか」を調べたい場合です。
例えば、文字列の中に含まれている数字を全部抜き出したいとします。
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher("abc123def45xyz6");
Javaここで matches() を使うと false です。
全体が数字だけではないからですね。
部分一致を見つけたいときは find() を使います。
while (matcher.find()) {
System.out.println("見つかった: " + matcher.group());
}
Java出力はこんな感じになります。
見つかった: 123
見つかった: 45
見つかった: 6
find() は「次の一致箇所があるか?」を順番に探していくメソッドです。while (matcher.find()) の形で使うと、「全部のマッチ」を順番に列挙できます。
group / start / end で「どこがマッチしたか」を取り出す
group() で一致した文字列を取り出す
さっきの例で使った group() は、「今のマッチで一致した文字列そのもの」を返します。
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher("abc123xyz");
if (matcher.find()) {
System.out.println(matcher.group()); // 123
}
Javamatches() を使った場合でも、true のあとに group() を呼べば、
「全体一致の文字列」が返ってきます。
Matcher matcher = pattern.matcher("12345");
if (matcher.matches()) {
System.out.println(matcher.group()); // 12345
}
Javastart と end で位置情報を知る
「どこに一致したか」まで知りたいときは start() と end() が使えます。
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher("abc123def");
if (matcher.find()) {
System.out.println("一致: " + matcher.group()); // "123"
System.out.println("開始位置: " + matcher.start()); // 3
System.out.println("終了位置: " + matcher.end()); // 6
}
Javastart() は「文字列のどのインデックスから始まったか」(0 始まり)。end() は「どこまでか(終端の1つ後のインデックス)」です。
この位置情報を使うと、自分で文字列を分割したり、
前後の文脈を参照したり、といった処理が書けるようになります。
グルーピング(())と group(n) の使い方(ここ大事)
括弧で「拾いたい部分」を囲う
正規表現の () は「グループ」を作ります。
Matcher では、グループごとに個別に取り出せます。
例えば「年-月-日」の形式から、それぞれの数字を取り出したい場合を考えましょう。
String text = "2025-12-31";
Pattern pattern = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
Matcher matcher = pattern.matcher(text);
if (matcher.matches()) {
String year = matcher.group(1); // 最初の ( ... )
String month = matcher.group(2); // 2番目の ( ... )
String day = matcher.group(3); // 3番目の ( ... )
System.out.println(year); // 2025
System.out.println(month); // 12
System.out.println(day); // 31
}
Javaここでのポイントは、
group(0) は「全体にマッチした文字列」(”2025-12-31″)
group(1) が1番目の括弧、group(2) が2番目の括弧…
という対応になっていることです。
この仕組みを使うと、「正規表現で形をチェックしながら、中の必要な部分だけ取り出す」ということができます。
find と組み合わせて複数マッチから情報を抜き出す
例えば、文章の中に日付がいくつも出てくるケース。
String text = "イベントは2025-12-31に開催され、予備日は2026-01-10です。";
Pattern pattern = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
String year = matcher.group(1);
String month = matcher.group(2);
String day = matcher.group(3);
System.out.println("見つかった日付: " + year + "/" + month + "/" + day);
}
Java出力は、
見つかった日付: 2025/12/31
見つかった日付: 2026/01/10
のようになります。
find() で「次のマッチ」を探し、
それぞれのマッチで group(n) を使って必要な部分を取り出す。
この組み合わせが、Matcher の強みの一つです。
置換に使う:replaceAll / replaceFirst
単純な置換:全部置き換える
Matcher は、「マッチした部分を置き換える」こともできます。
例えば、「数字だけを # に置き換える」例です。
String text = "商品Aは100円、商品Bは250円です。";
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(text);
String replaced = matcher.replaceAll("#");
System.out.println(replaced);
// 商品Aは#円、商品Bは#円です。
JavareplaceAll は、「マッチしたすべての部分」を置き換えます。replaceFirst を使うと、最初の1箇所だけ置き換えます。
String replacedFirst = matcher.replaceFirst("#");
System.out.println(replacedFirst);
// 商品Aは#円、商品Bは250円です。
Java元の文字列の他の部分は自動でコピーされる
replaceAll / replaceFirst を使うと、
マッチした部分 → 指定した文字列に変換
それ以外の部分 → そのままコピー
という処理をいい感じにやってくれます。
「マッチしない部分も含めて、全文を組み立て直す」のを自分でやると結構大変なので、
まずはこれらのメソッドで済むケースから使い始めると良いです。
reset / region など、Matcher の動きを制御する
reset で同じ Matcher を再利用する
Matcher は、一度 find() を進めたりすると内部に「今どこまで見たか」の状態を持ちます。
同じ文字列に対して、最初から検索し直したいときは reset() を使います。
Matcher matcher = pattern.matcher("abc123xyz");
while (matcher.find()) {
System.out.println(matcher.group());
}
matcher.reset(); // 最初の状態に戻す
while (matcher.find()) {
System.out.println("再検索: " + matcher.group());
}
Javareset("新しい文字列") のように、
「同じ Pattern だが、別の文字列に対して再利用する」こともできます。
matcher.reset("foo456bar");
while (matcher.find()) {
System.out.println(matcher.group()); // 456
}
Java頻繁にパターンを使い回す場面では、「Pattern は1つだけ作る → Matcher を reset しながら使う」というスタイルも可能です。
region で検索範囲を絞る(少し上級)
文字列の一部だけを対象に検索したいときは region(int start, int end) も使えます。
String text = "abc123def456ghi";
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(text);
// インデックス 3〜10 だけを検索対象にする
matcher.region(3, 10);
while (matcher.find()) {
System.out.println("region内で見つかった: " + matcher.group());
}
Javaこの例だと、"123def456" の範囲だけで数字を探します。
全体に対して find したくないケース(部分だけ検査したい)で使われますが、
初心者のうちは「そんな機能もあるんだ」くらいの理解で十分です。
まとめ:Matcher を使うときに覚えておきたいパターン
初心者向けに、Matcher の使い方をざっくりまとめるとこうなります。
Pattern.compile(正規表現) でパターンを作る
pattern.matcher(文字列) で Matcher を作る
「全体一致をチェックしたい」→ matcher.matches()
「文字列の中から全部見つけたい」→ while (matcher.find()) { matcher.group() }
「グループごとに取り出したい」→ 正規表現で (…) を使って、matcher.group(1), group(2)…
「位置も知りたい」→ matcher.start(), matcher.end()
「置換したい」→ matcher.replaceAll(), matcher.replaceFirst()
ここまで押さえておけば、Matcher でできることのかなりの部分は使いこなせます。

