後方参照によるパターン内での参照(¥1, ¥2, ..)

広告

パターン内で括弧を使用することで、括弧内のパターンにマッチする部分文字列が記憶されます。記憶された部分文字列はパターンマッチが完了すると変数「$1」などに格納されプログラムの中で利用することが出来ます。

このパターンにマッチし記憶された部分文字列をパターン内でも参照することが可能です。このように記憶された部分文字列をパターン内で参照することを後方参照と呼んでいます。記憶された部分文字列は最初に記憶された内容は「¥1」、次に記憶された内容は「¥2」のように参照することが可能となります。

記憶された値はパターン内で「¥1」「¥2」..で参照できる

では具体的な例として<h1>で始まる場合は</h1>までを、<h2>で始まる場合は</h2>までをマッチさせる正規表現を考えてみます。

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

上記のパターンではまず「<(h1|h2)>」の部分で「<h1>」又は「<h2>」のどちらかにマッチします。この時マッチした「h1」又は「h2」のどちらかが記憶されます。「.*」の部分で任意の文字にマッチします。そして「<¥/¥1>」の中の「¥1」の部分は既に記憶された文字列が参照されます。つまり「h1」が記憶されていれば「<¥/h1>」となり「h2」が記憶されていれば「<¥/h2>」にマッチします。(「/」はエスケープが必要なので「¥/」となっています)。

このように既にマッチした内容を使ってパターンそのものを記述する場合に使用します。

サンプルプログラム

では簡単なプログラムで確認して見ます。

test5-1.pl

use strict;
use warnings;
use utf8;
binmode STDIN, ':encoding(cp932)';
binmode STDOUT, ':encoding(cp932)';
binmode STDERR, ':encoding(cp932)';

print "パターン: /<(div|span)>.*</¥¥1>/¥n¥n";
&check("book is <div>2391yen</div>, cake is 800yen");
&check("today is <span>Friday</span>");

sub check{
  my ($str) = @_;

  if ($str =~ /<(div|span)>.*<¥/¥1>/){
    print "対象: $str¥n";
    print "$&¥n";
  }
}

上記を「test5-1.pl」の名前で保存します(文字コードはUTF-8です)。そしてコマンドプロンプトを起動し、プログラムを保存したディレクトリに移動してから次のように実行して下さい。

後方参照によるパターン内での参照(¥1, ¥2, ..)

( Written by Tatsuo Ikura )