単純な一致判定(完全一致、部分一致、前方一致、後方一致)のみであれば、【Java】文字列の完全一致と部分一致を判定する方法を参照して見て下さい。
抽出、置換、判定を繰り返し処理で行う場合は当記事を参照ください。
判定
以下が基本的な判定の手順です。
・正規表現を指定する。
・チェック対象文字列のMatcherを生成する。
・マッチするか実行する。
matches()
チェック対象文字列全体に対して一致しているかを判定します。
1 2 3 4 5 6 7 8 9 10 11 12 |
// 正規表現をコンパイルします Pattern pattern1 = Pattern.compile("[a-z]*"); // チェック対象文字列をMatcherに格納します Matcher matcher1 = pattern1.matcher("abc"); // 判定結果を取得します if (matcher1.matches()) { System.out.println("マッチしました。"); } else { System.out.println("マッチしませんでした。"); } |
マッチしました。
find()
チェック対象文字列全体に正規表現の一致箇所を順次判定します。
1 2 3 4 5 6 7 8 9 10 |
// 正規表現をコンパイルします Pattern pattern2 = Pattern.compile("[a-z]{3}"); // チェック対象文字列をMatcherに格納します Matcher matcher2 = pattern2.matcher("abc_def"); // 判定結果を取得します while (matcher2.find()) { System.out.println(matcher2.group()); } |
abc
def
抽出
抽出する場合、正規表現内に()で抽出箇所を明示的に示し、group()メソッドで抽出します。
()の数がgroup()メソッドのインデックスに当てはまります。
正規表現が「([a-z])_([A-Z])_([0-9])」である場合、以下のようにindexが割り当てられます。
([a-z]):index=1
([A-Z]):index=2
([0-9]):index=3
つまり、([a-z])の部分を抽出するには group(1)
とします。
ただし、index=0は全体を表すので、group(0)とgroup()は等価になります。
部分の抽出はindex=1から始まることに注意して下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// 正規表現をコンパイルします // ()で囲われた部分により抽出箇所を特定できます(後述) Pattern p = Pattern.compile("([a-z]*)_([A-Z]*)_([0-9]*)"); // チェック対象文字列をMatcherに格納します Matcher m = p.matcher("abc_XYZ_012"); // 抽出箇所の特定は、事前にmatchesメソッドを実行する必要があります m.matches(); // 抽出箇所はgroup()メソッドで取得します // group()とgroup(0)は等価です // 正規表現の()は左からindex=1で取得できます System.out.println("group() = : " + m.group()); for (int i = 0; i <= m.groupCount(); i++) { System.out.println("group(" + i + ") = : " + m.group(i)); } |
group() = : abc_XYZ_012
group(0) = : abc_XYZ_012
group(1) = : abc
group(2) = : XYZ
group(3) = : 012
置換
置換で使うことができるメソッドは主に4つあります。
全置換(replaceAll)
文字列全体に対して一致する箇所全てを置換します。
1 2 3 |
Pattern p1 = Pattern.compile("cat"); Matcher m1 = p1.matcher("one cat two cats."); System.out.println(m1.replaceAll("dog")); |
one dog two dogs.
部分置換(appendReplacement)
appendReplacementは全置換する過程で個別処理を差し込みたいケースで活用できます。
appendReplacementで全置換することもできますが、全置換であればreplaceAllの方が単純です。
また、appendReplacementはappendTailとセットで使う点に注意して下さい。
以下のコード例では、2回目の出現箇所のみ置換するようにしています。
1 2 3 4 5 6 7 8 9 10 11 12 |
Pattern p2 = Pattern.compile("cat"); Matcher m2 = p2.matcher("one cat two cats."); StringBuilder sb = new StringBuilder(); int occurrences = 1; while (m2.find()) { if (occurrences == 2) { m2.appendReplacement(sb, "dog"); } occurrences++; } m2.appendTail(sb); System.out.println(sb); |
one cat two dogs.
最初に一致した文字だけ置換(replaceFirst)
最初に一致した部分だけを置換するにはreplaceFirstを使用します。
1 2 3 |
Pattern p3 = Pattern.compile("a"); Matcher m3 = p3.matcher("First a, second a."); System.out.println(m3.replaceFirst("A")); |
First A, second a.
エスケープ文字を含む置換(quoteReplacement)
エスケープを含む文字の置換ではquoteReplacementを使用します。
以下のコード例では「slash」を「\」に置換しています。
quoteReplacementを使用すると置換に成功しますが(1)、使用しないとIllegalArgumentExceptionがthrowされます(2)。
1 2 3 4 |
Pattern p4 = Pattern.compile("slash"); Matcher m4 = p4.matcher("This is slash."); System.out.println(m4.replaceAll(Matcher.quoteReplacement("\\"))); // (1) System.out.println(m4.replaceAll("\\")); // (2) |
This is \.■出力結果(2)
Exception in thread “main” java.lang.IllegalArgumentException: character to be escaped is missing
チェッカーツール
Web上で公開されているJava用の正規表現チェッカーツールを紹介します。
Regular Expression Test Drivefor Java Developer
使い方は簡単で直感的です。
また、Patternのフラグ設定も可能になっているので、詳細な指定をしたい方はそれらを使用することもできます。
よく使う正規表現一覧
正規表現 | 説明 |
---|---|
. | 任意の1文字(行末記号とマッチする場合もある) |
\d | 数字: [0-9] |
\s | 空白文字 |
\w | 英数字: [a-zA-Z_0-9] |
[a-zA-Z] | a - zまたはA - Z (範囲指定) |
[^abc] | a、b、c以外の文字(否定) |
\t | タブ文字 |
\n | 改行文字 |
\r | キャリッジ・リターン文字 |
\\ | バックスラッシュ文字 |
^ | 行の先頭 |
$ | 行の末尾 |
\n | マッチしたn番目の前方参照を行う正規表現グループ |
更に詳細を確認したい場合は、PatternクラスのAPIドキュメントが参考になります。
【Java Doc】Patternクラス
String.matches v.s. Matcher.matches
単純な一致判定であればString.matchesを使うこともできます。
【Java】文字列の完全一致と部分一致を判定する方法
しかし抽出、置換を行いたいのであればPattern/Matacherを使うことをお薦めします。
また、一致判定であっても何度も繰り返す場合、性能的にはPattern/Matacherの方が速くなります。
こちらの記事が参考になります。
What’s the difference between String.matches and Matcher.matches?
実装する用途に応じて使い分けるようにしましょう。
まとめ
- 判定にはmatchesとfindがある。
- 抽出は()で抽出箇所を指定して、group()メソッドで取得する。
- 置換には全置換、部分置換、最初に一致した文字の置換、エスケープ文字の置換ができる。
- 繰り返し処理で判定をする場合、String.matchesよりもMatcher.matchesの方が性能が良い。
参考情報
【Java Doc】Matcherクラス
【Java Doc】Patternクラス
【Java】文字列の完全一致と部分一致を判定する方法
コメント