一般に $&, $', $` を使うと処理速度が低下する。また,練習問題B2のように,ファイルを単位として処理する場合,処理速度が低下するだけでなく,メモリ不足などにより処理ができなくなることがある。

以下のようにすれば, $&, $', $` を使わなくとも,kwic1.pl と同じ処理ができる。(pos は未習。m/ /g でマッチした文字列の次の位置を返す関数。) こちらの方が kwic1.pl よりも長い文字列を単位として処理することができ,かつ処理速度も速い。

    kwic1a.pl
    --------------------------------------------------
    #検索文字列の指定
    $string = '\bjust\b';

    #前後の文脈の長さの指定
    $llen = 25;
    $rlen = 25;

    #ファイル単位で読み込む
    $/ = undef;

    while (<>) {

       #左の文脈が指定の長さより短くなることがないよう処理
       $_ = (' ' x $llen) . $_;

       #空行は " <p> " で置き換え
       s/ *\n\n+ */ <p> /g;

       s/ *\n */ /g;

       #$& の代りに $1 を使用するために,$string を ( ) で囲む
       while(/($string)/ig){

          $count++;

          #$& の代りに $1 を使用
          $key  =  $1;

          #マッチした位置の次の位置を取得
          $pos = pos $_;

          #substr ($`, -$llen) の代り
          $pre  =  substr ($_, ($pos - (length $key) - $llen), $llen);

          #substr ($', 0, $rlen) の代り
          $post =  substr ($_, $pos, $rlen);

          $file =  $ARGV;
          $file =~ s#.*/([^/]+)$#$1#;

          printf "%5d | %s | %${llen}s|%s|%-${rlen}.${rlen}s\n", 
                  $count, $file, $pre, $key, $post;

       }
    }

    exit;
    --------------------------------------------------

処理そのものができなくなる場合は別として,少し処理速度が低下する程度なら,処理速度は気にせず,自分にとってわかりやすい書き方をする方が現実的である。