パターン内での後方参照

広告

パターン内で括弧を使うことで後からマッチした部分文字列を参照することができますが、パターン内において既にマッチした文字列を参照することも可能です。括弧()で囲まれたパターンにマッチした文字列はメタ文字の"¥1"、"¥2"...でパターン内から参照できます。

具体的な例で確認します。

"(RED|red)¥1"

上記の場合、まずターゲット文字列"(RED|red)"にマッチするかどうかが評価されます。マッチした場合、このグループの部分にマッチした部分はパターン内で後方参照することができます。このグループのインデックスは1ですので、パターン内に記述された"¥1"はグループ1にマッチした部分文字列にマッチすることになります。

例えば"(RED|red)"が"RED"にマッチした場合、"¥1"も"RED"にマッチすることになります。この場合の"(RED|red)¥1"は"REDRED"と記載したのと同じことです。同じように"(RED|red)"が"red"にマッチした場合、"¥1"も"red"にマッチすることになります。この場合の"(RED|red)¥1"は"redred"と記載したのと同じことです。

つまり次の2つのパターンは同じことを表しています。

"(REDRED|redred)"

次に<h1>で始まる場合は</h1>までを、<h2>で始まる場合は</h2>までをマッチさせるパターンを考えてみます。 (正確には異なりますが、説明用なので簡略化しています)。

"<(h1|h2)>.*?<¥/¥1>"

このパターンの場合、"<(h1|h2)>"で"<h1>"にマッチした場合は"<¥/¥1>"は"</h1>"にマッチし、"<(h1|h2)>"で"<h2>"にマッチした場合は"lt;¥/¥1>"は"</h2>"にマッチします。

パターン内で後方参照を記述することで、既にマッチした部分文字列を同じものにマッチさせるといったパターンを作成することが可能になります。

サンプルプログラム

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

JSample4_1.java

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

class JSample4_1{
  public static void main(String args[]){
    String str1 = "Today is <div>Tuesday</div>";
    String str2 = "Border Color is <span>red</span>";
    String str3 = "<span>Hello</div>";

    String regex = "<(div|span)>.*?<¥¥/¥¥1>";
    Pattern p = Pattern.compile(regex);

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

    check(p, str1);
    check(p, str2);
    check(p, str3);
  }

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

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

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

p4-1

( Written by Tatsuo Ikura )