JDK1.4で正規表現ライブラリが追加される前は、JakartaプロジェクトのRegexpまたはOroを使って正規表現を扱っていました。ここではJakarta Regexpを使って前の例を書き換えることで、微妙な仕様の違いを見てみます。
Jakarta Regexpはorg.apache.regexp
パッケージに必要がクラスがあります。大体の所はREクラスがその機能を提供します。PatternとMatcherに分かれている標準の正規表現ライブラリとどちらが使いよいのか意見が分かれる処だと思いますが、さてどうでしょうか。
文字列で表されている正規表現からREオブジェクトを作成します。
String regexString = "[a-zA-Z_][a-zA-Z_0-9]*";
RE re = new RE(regexString);
この正規表現は前の例と同じです。REオブジェクトを作ると、正規表現でパターンマッチングを行いたい対象を指定して、パターンマッチングの処理を開始します。パターンマッチングを行いたい対象はStringかCharacterIteratorインタフェースを実装しているクラスになります。文字列以外にStreamやReaderを基にしたCharacterIteratorを実装したクラスが用意されていますので、不自由はないでしょう。
REオブジェクトは対象文字列のどこから調べるのか、そのオフセットを指定しますので、どこまで調べたのかを憶えておくようにします。
String target = "PatternオブジェクトとMatcherオブジェクトを一つにしたようなREオブジェクトで処理します。";
int index = 0;
while (re.match(target, index)) {
System.out.println(re.getParen(0));
index = re.getParenEnd(0);
}
マッチした部分はre.getParen(0)で取り出すことができます。
()を使ってパターンを参照するにはgetParen()の引数に1以上の値を指定することで可能です。前の例と同様に正規表現文字列を、"([a-zA-Z_])([a-zA-Z_0-9]*)"としておくと、getParen(0)はパターンにマッチする全体を、getParen(1)は最初に現れる左括弧に対応する部分を、getParen(2)は2番目に現れる左括弧に対応する部分を取得することができます。引数にいくらまで数値を指定できるかはRE#getParenCount()で取り出すことができますが、Matcher#groupCount()とは違って、getParenCount()はgetParen()に指定できる値+1が返されます。
int index = 0;
while (re.match(target, index)) {
System.out.println(re.getParen(0));
int n = re.getParenCount();
System.out.println(n);
for (int i = 0; i < n; i++) {
System.out.println(i + ":" + re.getParen(i));
}
index = re.getParenEnd(0);
}
大体同じ機能を提供しているメソッドで、微妙に違う仕様を味わってください。