Java | Java 標準ライブラリ:正規表現(Pattern)

Java Java
スポンサーリンク

正規表現と 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(正規表現文字列) でパターンをコンパイルし、matchermatches / find で実際にチェックする。
1回だけの簡単なチェックなら Pattern.matches(regex, input) で済ませられる。
形式チェック(数字だけ・英数字だけ・メールアドレスっぽいか等)から使い始めると馴染みやすい。
バックスラッシュは「正規表現」と「Java 文字列」の両方でエスケープが必要なので、"\\d", "\\." のように二重になることに注意する。

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