PerlやUNIXのgrepなどで欠かせない正規表現ですが、Javaでもこれを扱うためのパッケージjava.util.regexがJ2SE1.4からコアAPIに導入されました。ここでは、正規表現自体の詳細には触れず、クラスとそのメソッドの使い方についてのみ言及することにします。
まずは、具体的なサンプルを見てみましょう。サンプルは以下のような処理を行っています。
- 「javaまたはclassという拡張子が付いたファイル名を表す正規表現」と、入力文字列全体がマッチするかを「matches(マッチ)」によって調べる
- 入力文字列に正規表現にマッチする部分文字列があるかどうかを「find(検索)」により調べる
- 存在した場合には「group, start, endの各メソッドによってマッチした文字列情報を取り出す
- マッチした文字列を「replaceAll(置換)」により[file]に置換して出力する
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
PatternオブジェクトとMatcherオブジェクトの生成
Javaで正規表現を用いるためには2つのオブジェクトが必要です。
- 正規表現を表すオブジェクト(java.util.regex.Pattern オブジェクト)
- 入力シーケンス(マッチの対象となる文字列)を持ち、マッチを行うオブジェクト(java.util.regex.Matcher オブジェクト)
String型で表した正規表現を引数に取るPatternのクラスメソッドcompileによってPatternオブジェクトが生成されます。正規表現の文字面をString型で表す際、文字クラスなどに用いるバッククオートはバッククオートによってエスケープしなければなりません。
Matcher オブジェクトはPatternオブジェクトのmatcherメソッドによって生成されます。このMatcherオブジェクトから正規表現のマッチ・検索・置換などの各種メソッドを呼び出すことができます。
ここで必要な正規表現は、
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
となります(\bは単語境界を、\wは単語構成文字([a-zA-Z_0-9]に同じ)を表す文字クラスです)。
この正規表現に対して、
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
という入力シーケンスを与え、マッチを行います。
Matcherオブジェクトが持つメソッドは例えば以下のようなものがあります。
- マッチ:matches(戻り値/boolean)
matchesによって、入力シーケンス全体が正規表現に一致するかどうかを調べることができる - 検索:find (戻り値/boolean)
入力シーケンスが正規表現にマッチする文字列を含むかどうかを調べることができる - 置換:replaceAll (戻り値/String)
入力シーケンスを検索し、正規表現とマッチする部分を指定した文字列で置換し、その結果の文字列をString型として返す
マッチする部分が存在した場合、その部分の開始位置と終了位置がMatcherオブジェクトに保存されます。後でMatcherのインスタンスメソッドgroupでマッチした部分の文字列を取り出すことができ、 startとendにより開始/終了位置を調べることができます。
また、正規表現の一部を丸括弧()で囲うことでグループを複数指定することができますが、このグループはこれらのメソッドにint型の引数を与えて参照することができます。
上で示したソースプログラムでは、正規表現全体のうち、「拡張子を除いたファイル名」と「.(ドット)を除いた拡張子」に当たる正規表現がグループとして指定され参照されています。
引数 | 文字列 | |
---|---|---|
0 | マッチした文字列全体 | |
n(1以上の整数) | 左からn番目の開き括弧によって指定された部分シーケンスに対応する文字列 |
下表に、正規表現\b([A-Za-z_]\w*)\.(java|class)\bに対し文字列“Regex.java”を与えた際のgroupメソッドの戻り値を示しました。
groupによる指定 | 戻り値のString | |
---|---|---|
group(0) | Regex.java | |
group(1) | Regex | |
group(2) | java |
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
なお、groupCountメソッドはグループの個数を返します。グループが指定されていないときは0を返しますが、group(0)は表1にあるようにマッチした文字列全体を返すので問題なく動きます。
findはいったんマッチしたら次に呼び出された時にはマッチした文字列の次の位置から検索を始めます(図1)。lookingAtというメソッドも検索に使うことができますが、こちらはいったんマッチしても、再度呼び出されたときには入力シーケンスの最初から検索を開始します。
正規表現を用いるStringのメソッド
最も基本的なクラスであるStringクラスでも、J2SE1.4で追加されたmatches、replaceAll、splitなどのメソッドにおいて正規表現を使えるようになりました。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
単純な処理のみ行うときには、上のようにStringのメソッドを用いて楽にコードを書くことができます。ただしもちろん正規表現の再利用などはできないので、場合に応じて使い分けてください。
Copyright © ITmedia, Inc. All Rights Reserved.