後読みを使ったパターン

広告

後読みを行うパターンは"(?<="から")"の間に記述します。

"パターン(?<=後読みパターン)"
"(?<=後読みパターン)パターン"

後読みのパターンは、指定されたパターンがターゲット文字列の前にさかのぼって存在するかどうかを確認し、見つかった場合は見つかった文字列の最後の位置にマッチします。つまり後読みのパターンは位置にマッチするパターンです。次の例を見てください。

ターゲット文字列
"PaddingWidthSize is 30px"

パターン
"Width(?<=PaddingWidth)Size"

この場合、まずパターンの中の"Width"がターゲット文字列の中の"Width"にマッチし、残るターゲット文字列は"Size is 30px"となります。

Padding Width Size is 30px
------- ----- ------------
        Width

続いてパターンの中の"(?<=PaddingWidth)"がマッチするかどうか試します。後読みの場合は残っているターゲット文字列ではなく、既に見た部分の文字列をさかのぼって対象とします。今回はマッチします。後読みの場合は位置にマッチするだけなので、残っているターゲット文字列は"Size is 30px"のままです。

PaddingWidth Size is 30px
------------ ------------
       Width
PaddingWidth

最後にパターンの中の"Size"がマッチするかどうか試します。残っているターゲット文字列は"Size is 30px"なのでマッチします。

Padding Width Size  is 30px
------- ----- ---- --------
        Width Size

つまり"Width(?<=PaddingWidth)Size"のパターンは、"Width"の後に"Size"が続く文字列にマッチするが、条件として"Size"の前には"PaddingWidth"が無ければならないということです。

この時パターン全体にマッチした文字列は"WidthSize"となります。後読みパターンの部分はあくまで位置にマッチしているだけのため、マッチした部分文字列には含まれてきません。

もしターゲット文字列が"MarginWidthSize is 30px"だったら、後読みパターンにマッチしないためパターン全体もマッチしません。またパターン文字列が"WidthSize"だったらターゲット文字列が"PaddingWidthSize is 30px"であっても"MarginWidthSize is 30px"であってもマッチします。

先読み同様に後読みも分かりにくいですが便利な機能なので是非理解しておいて下さい。

否定の後読み

後読みの場合も否定の後読みが用意されています。書式は次の通りです。

"パターン(?<!後読みパターン)"
"(?<!後読みパターン)パターン"

基本的な考え方は同じで、後読みパターンに記載したパターンに一致しない場合に"(?<!後読みパターン)"が一致します。

サンプルプログラム

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

JSample3_1.java

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

class JSample3_1{
  public static void main(String args[]){
    String str1 = "MarginWidthSize is 20px";
    String str2 = "PaddingWidthSize is 30px";

    String regex1 = "Width";
    Pattern p1 = Pattern.compile(regex1);

    String regex2 = "Width(?<=PaddingWidth)Size";
    Pattern p2 = Pattern.compile(regex2);

    System.out.println("パターン : " + regex1);

    check(p1, str1);
    check(p1, str2);

    System.out.println("パターン : " + regex2);

    check(p2, str1);
    check(p2, str2);
  }

  private static void check(Pattern p, String target){
    Matcher m = p.matcher(target);

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

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

p3-1

( Written by Tatsuo Ikura )