正規表現処理その1

JDK1.4からCoreのクラスライブラリにも正規表現の処理用クラスが提供されました。パッケージjava.util.regexがそれです。正規表現はUnixではgrep、sedを始めとして様々なプログラムでサポートされている、文字列処理のための機能です。プログラミング言語のPerlは、豊富な正規表現機能をサポートしているので文字列処理をするのに非常に便利であることをご存知の方も多いでしょう。Unixのライブラリにはもともと正規表現を処理するための関数が用意されていました(Perlは独自に実装していますが)ので、色々なプログラムで統一的に正規表現機能を提供できたわけですが、Javaでもこうしたことができるようになったわけです(これまででもJakarta OroやJakarta Regexpを使えばできましたが)。

java.util.regexの使い方は比較的シンプルです。正規表現の文字列を基にPatternオブジェクトを作成し、そこから正規表現検索エンジンであるMatcherオブジェクトを作成し、あとはMatcherオブジェクトのメソッドを呼び出すことで必要な処理を行うことができます。このあたりは実際にプログラムを作って動かしてみることで、その機能をよく理解することができます。

まずPatternオブジェクトを作成します。正規表現そのものは文字列で表現されていますからこれを変換(コンパイルと表現するようですが)してPatternオブジェクトを作成します。

	String regexString = "[a-zA-Z_][a-zA-Z_0-9]*";
	Pattern pattern = Pattern.compile(regexString);
この正規表現は先頭が英字(アンダースコアを含む)で、2文字目以後は英数字であるような長さが1以上の文字列を表しています(もう少し簡単に表現できますが、とりあえずべたで)。Patternのcompileメソッドを呼んでPatternオブジェクトに変換することができます。

Patternオブジェクトを作ると、ここから正規表現でパターンマッチングを行いたい対象を指定して、正規表現検索エンジンであるMatcherオブジェクトを生成します。パターンマッチングを行いたい対象はCharSequenceインタフェースを実装している必要がありますが、java.lang.Stringやjava.lang.StringBuffer、java.nio.CharBufferといったクラスがCharSequenceを実装していますので、これらを利用することになります。

	String target = "まずPatternオブジェクトを作成します。次にMatcherオブジェクトを作成します。";
	Matcher matcher = pattern.matcher(target);

Matcherオブジェクトができたら、対象文字列を前から順に調べてゆきます。 Matcherオブジェクトはどこまで調べたかを憶えておいてくれるので、find()メソッドがfalseになるまでループにしておけば、対象文字列の最後まで調べることができます。上記の例ならば、"Pattern"と"Matcher"の処が正規表現にマッチする部分になります。正規表現にマッチする部分を標準出力に出す場合は、

	while (matcher.find()) {
		System.out.println(matcher.group());
	}
となります。

さて、正規表現には()を使ってパターンを参照する機能があります。例えば先ほどの例で正規表現文字列を、"([a-zA-Z_])([a-zA-Z_0-9]*)"としてみます。これは先頭文字とそれ以後の文字列それぞれの部分を参照できるようにしています。groupメソッドにintの引数を指定することで、この括弧の中にアクセスすることができます。

group(0)はgroup()と同じ文字列、つまりパターン全体を返します。それ以後はパターン内の左括弧が現れる順に参照することができます。即ちgroup(1)は最初の括弧で囲まれる部分、つまり先頭文字の部分を返し、group(2)はそれに続く文字列を返します。引数にいくらまで番号を指定できるかはgroupCount()メソッドで知ることができます。

	while (matcher.find()) {
		System.out.println(matcher.group());
		int n = matcher.groupCount();
		System.out.println(n);
		for (int i = 0; i <= n; i++) {
			System.out.println(i + ":" + matcher.group(i));
		}
	}

正規表現と対象文字列を色々変えて試してみるとMatcherの動作が良くわかると思います。


人材開発室 PoisonSoft