正規表現と Pattern クラスの関係をざっくりつかむ
「正規表現(regex)」は、
「文字列の **“パターン” を言葉で書くための小さな言語」
だと思ってください。
「数字3桁‐数字4桁の電話番号」
「@ を含むメールアドレスらしき文字列」
「半角英数字だけからなる文字列」
といった「形」にマッチさせるのが得意です。
Java では、この「パターン」を扱うために java.util.regex.Pattern クラスが用意されています。Pattern は「正規表現をコンパイルした結果」を表すクラスで、そのパターンを使って実際に文字列とマッチングするのは Matcher クラスです。
イメージとしては、
正規表現の文字列 → Pattern に「コンパイル」 → Pattern から Matcher を作る → 文字列にマッチするか調べる
という流れになります。
Pattern クラスの基本的な使い方の流れ
1. 正規表現パターンをコンパイルする
正規表現は、まず Pattern.compile に文字列として渡し、Pattern オブジェクトに変換します。
import java.util.regex.Pattern;
Pattern p = Pattern.compile("a*b");
Javaこの例だと、「b の前に a が 0 回以上並ぶパターン」(例: "b", "ab", "aaab" など)を表す Pattern になります。
この「compile(コンパイル)」は、「そのパターンを何度も使えるように準備しておく」イメージです。
2. Pattern から Matcher を作る
次に、そのパターンを使って、実際の文字列と照らし合わせる Matcher を作ります。
import java.util.regex.Matcher;
Matcher m = p.matcher("aaab");
Javaこの時点では「まだマッチングはしていない」。
「この文字列をチェック対象にしますよ」と準備しただけです。
3. Matcher でマッチングを実行する
最後に、Matcher のメソッドを使って「一致しているか」「どこに一致があるか」を調べます。
全体がパターンと一致するかを調べるには matches() を使います。
boolean result = m.matches(); // "aaab" が a*b にマッチするか?
System.out.println(result); // true
Java「部分的にでも含まれているか?」を調べたい場合は find() を使います。
(これは後で少し詳しく触れます。)
まずは「形式チェック」から始めるのがおすすめ
例1:数字だけからなる文字列かどうか
「入力が数字だけかチェックしたい」という超定番問題で考えてみます。
Pattern p = Pattern.compile("\\d+"); // 「1文字以上の数字」
Matcher m = p.matcher("12345");
boolean ok = m.matches(); // 全体が数字だけなら true
System.out.println(ok); // true
Javaここでのポイントは、
\d は「数字 0〜9」の意味+ は「1 回以上の繰り返し」
なので、\d+ で「1文字以上の数字だけ」というパターンになります。
Java の文字列リテラルでは \ 自体をエスケープする必要があるので、
コードでは "\\d+" と書きます(ここは正規表現のつまずきポイントその1)。
例2:メールアドレスっぽい文字列かどうか(ざっくり)
完璧なメールアドレス判定は難しいですが、
「とりあえず @ と ドメインっぽいものがあるか」を簡略化してチェックしてみます。
Pattern p = Pattern.compile("[\\w._%+-]+@[\\w.-]+\\.[A-Za-z]{2,}");
Matcher m = p.matcher("taro@example.com");
boolean ok = m.matches();
System.out.println(ok); // true(簡易チェックとして)
Javaここでは少し複雑なパターンを使っていますが、
最初は「全部理解しよう」としなくて構いません。
「正規表現にはこういう“形”を表現できる」という感覚だけ掴んでおけば十分です。
matches / find / lookingAt の違い(ここはしっかり)
matches:文字列全体がパターンと一致するか
Matcher#matches() は「文字列全体が パターンに一致するか」を見ます。
Pattern p = Pattern.compile("\\d+");
Matcher m1 = p.matcher("123");
Matcher m2 = p.matcher("abc123xyz");
System.out.println(m1.matches()); // true
System.out.println(m2.matches()); // false(全体が数字だけではない)
Java「入力欄の形式チェック」など、「全部がそうなっていてほしい」場面では matches() を使うのが基本です。
find:どこかにそのパターンが含まれているか
find() は、「どこか一部分でも パターンに一致する箇所があるか」を調べます。
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("abc123xyz");
while (m.find()) {
System.out.println("見つかった: " + m.group());
}
Javaこのコードは "123" を見つけて、「見つかった: 123」と表示します。
find() を使うと、テキストの中から複数箇所を次々に見つけることができます。
lookingAt:先頭からパターンが始まっているか
lookingAt() は、「文字列の先頭から パターンに一致しているか」を調べます。
Pattern p = Pattern.compile("\\d+");
Matcher m1 = p.matcher("123abc");
Matcher m2 = p.matcher("abc123");
System.out.println(m1.lookingAt()); // true(先頭が数字)
System.out.println(m2.lookingAt()); // false(先頭は a)
Javaまとめると、
matches() → 全体一致find() → 部分一致(どこかに含まれていれば OK)lookingAt() → 先頭一致
という棲み分けです。
初心者は、まず matches() と find() の2つを押さえておけば十分です。
Pattern の便利ショートカット:Pattern.matches(...)
1回だけのチェックなら static メソッドでも OK
「とりあえず一回だけ形式チェックしたい」だけなら、Pattern.compile → matcher → matches を毎回書くのは面倒なので、Pattern クラスの static メソッド matches が使えます。
import java.util.regex.Pattern;
boolean ok = Pattern.matches("\\d+", "12345");
System.out.println(ok); // true
Javaこのメソッドは内部で
Pattern.compile(regex)pattern.matcher(input).matches()
を一度だけ実行してくれます。
注意点としては、「毎回 compile される」ので、
同じ正規表現を何度も使い回す → Pattern を変数として保持したほうが効率的
一回きり → Pattern.matches で簡潔に書ける
と使い分けるとよいです。
よく使う正規表現パターンをいくつか体に馴染ませる
数字関連
数字だけ(1文字以上):
Pattern p = Pattern.compile("\\d+");
Java数字だけ(桁数固定、例: 3桁):
Pattern p = Pattern.compile("\\d{3}");
Java数字 3〜5 桁:
Pattern p = Pattern.compile("\\d{3,5}");
Java英字・英数字
半角英字だけ:
Pattern p = Pattern.compile("[A-Za-z]+");
Java半角英数字だけ:
Pattern p = Pattern.compile("[A-Za-z0-9]+");
Java英数字 + アンダースコア(\w):
Pattern p = Pattern.compile("\\w+");
Javaこういう「よく使う形」は、最初は丸暗記で構いません。
使っているうちに、「[] は文字の集合」「+ は 1 回以上」「{n,m} は回数指定」などの感覚が自然についていきます。
エスケープの二重構造に注意(ここは最初の山)
「正規表現としてのエスケープ」と「Java 文字列としてのエスケープ」
ここが初心者の一番のつまずきポイントです。
正規表現自体にも「エスケープ」が必要な文字があります。
例えば
. → 「何か1文字」の意味になるので、普通のドットとして扱いたいときは \.\d → 「数字」、\s → 「空白」 などの「バックスラッシュから始まる特殊記号」
などです。
ところが Java の文字列リテラルでも \ はエスケープの開始記号なので、
コード上は "\d" と書くと「\d」ではなく「d」になってしまいます。
そのため、Java で正規表現を書くときはたいてい「\ を二重に書く」必要があります。
例:
正規表現としては \d+(数字1文字以上)
Java のコードでは "\\d+" と書く
正規表現としては \.(単なるドット)
Java のコードでは "\\." と書く
これに慣れるまでは、「とりあえず \ は二重に書く」と覚えておくのでも構いません。
まとめ:Pattern をどう使いこなしていくか
初心者として、Pattern と正規表現をこう捉えておくと良いです。
正規表現は「文字列の形(パターン)を表す小さな言語」。
Java では Pattern.compile(正規表現文字列) でパターンをコンパイルし、matcher → matches / find で実際にチェックする。
1回だけの簡単なチェックなら Pattern.matches(regex, input) で済ませられる。
形式チェック(数字だけ・英数字だけ・メールアドレスっぽいか等)から使い始めると馴染みやすい。
バックスラッシュは「正規表現」と「Java 文字列」の両方でエスケープが必要なので、"\\d", "\\." のように二重になることに注意する。
