リージョンの設定

広告

まずはリージョンを設定し、マッチするかどうかの対象となるターゲット文字列の範囲を設定する方法を確認します。

正規表現を使う手順は今まで次のように行っていました。

String str = "abcdef";
String regex = "abc";
Pattern p = Pattern.compile(regex);

Matcher m = p.matcher(str);
if (m.find()){
  System.out.println("マッチしました");
}

パターンを定義し、ターゲット文字列とパターン文字列からパターンオブジェクトを作成してから、今度はマッチャオブジェクトを作成しました。

ではターゲット文字列の中の一部の範囲だけを対象にする場合にどの段階で指定を行うのかというと、マッチャに対して範囲を指定します。同じマッチャに対してリージョンを設定したり、それをリセットしたりすることが可能です。

ではリージョンを設定してみます。リージョンの設定を行うにはMatcherクラスで定義されているregionメソッドを使用します。

正規検索エンジンの領域に制限を設定します。領域は、マッチの検索対象となる入力シーケンスの一
部です。このメソッドを呼び出すと、正規検索エンジンがリセットされ、領域の先頭が start パラ
メータにより指定されたインデックスに、領域の末尾が end パラメータにより指定されたインデッ
クスにそれぞれ設定されます。

使用される透明度とアンカー設定によっては (useTransparentBounds および useAnchoringBounds 
を参照)、アンカーなどの特定の作成上の振る舞いが領域の境界またはその付近で異なる場合があり
ます。

パラメータ:
  start - 検索を開始する位置のインデックス (その値も含む)
  end - 検索を終了する位置のインデックス (その値を含まない) 
戻り値:
  この正規表現エンジン 
例外:
  IndexOutOfBoundsException - start または end がゼロより小さい場合、start が入力シーケン
    スの長さより大きい場合、end が入力シーケンスの長さより大きい場合、または start が end
    より大きい場合

1番目の引数には開始インデックス、2番目の引数には終了インデックスを指定して下さい。例えば先頭の文字はインデックス0、次の文字はインデックス1となります。region(0, 1)と指定すれば、0番目の文字から1番目の文字となりますが、開始インデックスの文字は含みますが終了インデックスの文字は含みませんので結果的に0番目の文字だけが対象となるリージョンとなります。

なおregionメソッドを実行するとマッチャがリセットされます。findメソッドを連続で使っている途中で実行する場合は注意して下さい。

次の例を見てください。

String str = "border width is 100px, and border height is 80px";
String regex = "¥¥d+";
Pattern p = Pattern.compile(regex);

Matcher m = p.matcher(str);
if (m.find()){
  System.out.println(m.group());
}

パターンは数字が1文字以上続くものですので、上記の場合はパターンがマッチし、マッチした部分は"100"となります。

次にリージョンを設定します。

String str = "border width is 100px, and border height is 80px";
String regex = "¥¥d+";
Pattern p = Pattern.compile(regex);

Matcher m = p.matcher(str);
m.region(21, 48);

if (m.find()){
  System.out.println(m.group());
}

パターンは先ほどと同じですがリージョンが21文字目から48文字目までに設定されています。よってマッチするかどうかの対象となる文字列は", and border height is 80px"となります。結果として上記の場合はパターンがマッチし、マッチした部分は"80"となります。

リージョンの設定が有効となるメソッド

リージョンを設定することで対象となる文字列の範囲を指定することができますが、全てのメソッドで有効となるわけではありません。

有効:

find()
lookingAt()
matches()

無効:

find(int start)
replaceAll(String replacement)
replaceFirst(String replacement)

引数有りのfindメソッドと置換を行うreplaceAllメソッドとreplaceFirstメソッドは、メソッドが実行されるとまずリセットが行われます。その為、事前にリージョンを設定していも意味を持ちません。

サンプルプログラム

では実際に試してみます。

JSample1_1.java

import java.util.regex.Pattern;
import java.util.regex.Matcher;

class JSample1_1{
  public static void main(String args[]){
    String str = "border width is 100px, and border height is 80px";

    String regex = "¥¥d+px";
    Pattern p = Pattern.compile(regex);

    System.out.println("パターン : " + regex);
    System.out.println("ターゲット文字列 : ¥"" + str + "¥"");

    Matcher m = p.matcher(str);

    int start = m.regionStart();
    int end = m.regionEnd();

    System.out.println("¥nデフォルトのままマッチ:");
    System.out.println("region : ¥"" + str.substring(start, end) + "¥"");

    if (m.find()){
      System.out.println("match:" + m.group());
    }else{
      System.out.println("×");
    }

    /* マッチャをリセットしリージョンを設定 */
    start = str.indexOf(',');
    end = str.length();
    m.region(start, end);

    System.out.println("¥nリージョン設定(" + start + "," + end + ")");
    System.out.println("region : ¥"" + str.substring(start, end) + "¥"");

    if (m.find()){
      System.out.println("match:" + m.group());
    }else{
      System.out.println("× ");
    }

    /* マッチャをリセットしリージョンを設定 */
    end = start;
    start = 0;
    m.region(start, end);

    System.out.println("¥nリージョン設定(" + start + "," + end + ")");
    System.out.println("region : ¥"" + str.substring(start, end) + "¥"");

    if (m.find()){
      System.out.println("match:" + m.group());
    }else{
      System.out.println("×");
    }
  }
}

ではコンパイルを行った上で実行してみます。

p1-1

( Written by Tatsuo Ikura )