一般に $&, $', $` を使うと処理速度が低下する。また,練習問題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; --------------------------------------------------
処理そのものができなくなる場合は別として,少し処理速度が低下する程度なら,処理速度は気にせず,自分にとってわかりやすい書き方をする方が現実的である。