プログラミングで複雑なルールによる入力チェックや、文字列置換を行いたい時に正規表現を使えると非常に便利です。
複雑な入力チェックの処理をいくつも記述すると分かりづらいコードで、不具合の原因となる場合もあります。
正規表現を用いるとシンプルな記述方法で、簡潔なロジックで表すことができます。
その一方で、正規表現自体の記述方法はルールがたくさんあり、すべてを覚えるのは困難です。
必要な時に調べれば良いので、すべてを覚える必要はないと思いますが、どんなことができるのかは知っておく必要があります。
そこで本記事では、Javaの正規表現についての記述方法やできることについてまとめます。
プログラミング初心者の方の学習や、忘れてしまった方の復習として、参考にしていただければ幸いです。
記載しているプログラムは、Java11を使って動作確認をしています。
Javaの正規表現
Javaの正規表現として以下の内容を採り上げます。
- 正規表現の作成方法
- 正規表現による文字列チェック
- 正規表現による文字列置換
- 正規表現による文字列抽出
- 正規表現のエスケープ
正規表現の作成方法
Javaで正規表現を扱うには、標準で提供されている java.util.regexパッケージ を使います。
java.util.regexパッケージには2つのクラスがあります。
- Patternクラス:正規表現をコンパイルします。
- Matcherクラス:コンパイルした正規表現を使って、マッチ操作を行います。
上記の2つのクラスを使って、正規表現による操作を行います。
また、Stringクラスが提供するメソッドに、直接正規表現を指定して操作を行うことも可能です。
何度も同じ正規表現を利用する場合はコンパイルして使うほうが効率よく使うことができます。
本記事では両方の操作方法について解説します。
正規表現にはたくさんの特殊文字やオプションがありますが、詳細はAPIリファレンスをご参照ください。
正規表現による文字列チェック
正規表現による文字列チェックは、StringクラスとMatcherクラスのmatches、およびMatcherクラスのfindを使う方法があります。
matchesメソッド
matchesメソッドは、指定した文字列が正規表現にマッチするはtrueを返し、マッチしない場合はfalseを返します。
str = "Hello Java!!"; regex = ".+Java.+"; System.out.println(str.matches(regex)); // -> true p = Pattern.compile(regex); System.out.println(p.matcher(str).matches()); // -> true
なお、Patternクラスでコンパイルする際に、オプションを指定することができます。
よく使われるのは、大文字小文字を区別せずにマッチさせるオプションです。
str = "Hello Java!!"; regex = ".+java.+"; System.out.println(str.matches(regex)); // -> false p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); System.out.println(p.matcher(str).matches()); // -> true
findメソッド
findメソッドは、正規表現にマッチする次の部分シーケンスを検索します。
1回目に呼出すと先頭から最初にマッチした部分シーケンスを取得でき、2回目に呼出すと次にマッチした部分シーケンスを取得できます。
str = "Hello Java!!"; regex = "\\w+"; p = Pattern.compile(regex); m = p.matcher(str); if (m.find()) { System.out.println(m.group()); // -> Hello } if (m.find()) { System.out.println(m.group()); // -> Java }
上記のプログラムでは、findメソッドによってマッチしているどうかを確認し、マッチしている場合はgroupメソッドによって一致した文字列を取得しています。
正規表現に指定している「\w+」は、英字・数字・アンダースコアのいずれかが1文字以上続くことを表す正規表現です。
正規表現による文字列置換
正規表現による文字列置換は、replaceAll、replaceFirstを使います。
どちらのメソッドもStringクラス、Matcherクラスで利用することができます。
replaceAllメソッド
replaceAllメソッドは、正規表現にマッチする文字列をすべて置換します。
str = "Hello Java!!"; regex = "\\w"; rep = "*"; System.out.println(str.replaceAll(regex, rep)); // -> ***** ****!! p = Pattern.compile(regex); System.out.println(p.matcher(str).replaceAll(rep)); // -> ***** ****!!
上記のプログラムでは英字をアスタリスクに置換しています。
replaceFirstメソッド
replaceFirstメソッドは、正規表現に最初にマッチした文字列のみを置換します。
str = "Hello Java!!"; regex = "\\w"; rep = "*"; System.out.println(str.replaceFirst(regex, rep)); // -> *ello Java!! p = Pattern.compile(regex); System.out.println(p.matcher(str).replaceFirst(rep)); // -> *ello Java!!
正規表現による文字列抽出
正規表現で指定した部分を文字列から抽出するには、抽出したいパターンに括弧を含めて指定します。
replaceAllメソッドで抽出した文字列を使って置換をする場合は、抽出した文字列を$1、$2を使って取得します。
str = "Hello Java!!"; regex = "(\\w+)\\s(\\w+)!!"; System.out.println(str.replaceAll(regex, "$2 $1")); // -> Java Hello p = Pattern.compile(regex); System.out.println(p.matcher(str).replaceAll("$2 $1")); // -> Java Hello
matchesメソッドで一致した文字列を抽出する場合は、groupメソッドに取得したいインデックスを指定します。
1つ目に一致した文字列を抽出する場合はインデックス1、2つ目に一致した文字列を抽出する場合はインデックス2となります。
また、インデックス0でマッチした文字列全体を取得することができます。
str = "Hello Java!!"; regex = "(\\w+)\\s(\\w+)!!"; p = Pattern.compile(regex); m = p.matcher(str); if (m.matches()) { System.out.println(m.group(0)); // -> Hello Java!! System.out.println(m.group(1)); // -> Hello System.out.println(m.group(2)); // -> Java }
正規表現のエスケープ
正規表現においてピリオドやプラス、アスタリスクなどの記号は、特殊文字として定義されている文字です。
これらを文字列に含んでいる場合の正規表現を作成する場合は、特殊文字として扱われないようにエスケープする必要があります。
エスケープは、特殊文字の直前にバックスラッシュを付けます。
また、Javaでは文字列中のバックスラッシュが特別な意味を持つため、バックスラッシュをエスケープするためにさらにバックスラッシュを付ける必要があります。
str = "Hello+Java."; regex = "\\w+\\+\\w+\\."; System.out.println(str.matches(regex)); // -> true p = Pattern.compile(regex); System.out.println(p.matcher(str).matches()); // -> true
上記のプログラムでは、プラスとピリオドの直前にバックスラッシュを入れてエスケープした正規表現を作成しています。
正規表現はプログラム外でも役に立つ
正規表現はプログラムをシンプルにしてくれる便利なものですが、プログラム外でも役に立つことがあります。
エディタを使って文章を書いている際に、文字列の検索や置換をしたくなった場合に、正規表現で指定することが可能なエディタもあります。
Linuxのコマンドでも正規表現を使えるコマンドがたくさんあります。
Excelの関数などでも正規表現を使うことができます。
正規表現で書いてみたけど、思うようにマッチしないという場合には、正規表現チェッカーというツールで分かりやすく一致部分を表現してくれるツールもありますので活用してみてください。
正規表現は記述方法が難しいのですが、書けると非常に効率を上げてくれる手段になります。
サラッと正規表現を書ける人はカッコいいですよね。
今回はJavaの正規表現についてまとめました。
以上、参考になれば幸いです。
コメント