Lesson 4





練習問題A


1.  kwic2.pl の最初の3行の意味を確認しなさい。

kwic2.pl
----------     ----------
#ディスプレー(STDERR)に「SEARCH STRING: 」を出力(表示)
print STDERR "SEARCH STRING: ";

# $string にキーボードから入力される文字列を代入
$string = <STDIN>;

#入力された文字列には改行が含まれてしまう。chompで区切り文字(\n)を削除

chomp $string;


$/ = "";

while(<>){

    s/ *\n */ /g;

    while(/$string/ig){

        $count++;
        $key = $&;
        $pre = substr ($`, -25);
        $post = substr ($', 0, 25);

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

        printf "%5d | %s | %25s|%s|%-25.25s\n",
                  $count, $file, $pre, $key, $post;
    }
}

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



.  kwic2.pl を書き換えて,検索文字列の左右の文脈の長さもコマンドラインから指定できるようにしなさい。

kwic2-1.pl
----------     ----------
print STDERR "SEARCH STRING: ";
$string = <STDIN>;
chomp $string;

print STDERR "DIGITS BEFORE SEARCH STRING: ";
$numpre = <STDIN>;
chomp $numpre;

print STDERR "DIGITS AFTER SEARCH STRING: ";
$numpost = <STDIN>;
chomp $numpost;





$/ = "";

while(<>){

   s/ *\n */ /g;

   while(/$string/ig){

      $count++;

      $key  =  $&;
      $pre  =  substr ($`, -$numpre);
      $post =  substr ($', 0, $numpost);

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

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

   }
}

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


練習問題B

.  練習Aで書き換えたスクリプトに,さらに次の2つの機能を付け加えなさい。
            a
.  検索文字列として不適切なものが指定されたら,メッセージを出力して終了する。
            b
.  右と左の文脈の長さの最小値・最大値を設定し,最小値より小さい値が指定されたときは最小値を,最大値より大きな値が指定された場合には最大値を値とするようにする。長さが指定されなかった場合にはデフォルトの値 (たとえば 25) を使う。

kwic2-2.pl
----------     ----------
print STDERR "SEARCH STRING: ";
$string = <STDIN>;
chomp $string;


if($string =~ /^[ \n\r\t]+$/){

   print STDERR "INVALID SEARCH STRING\n";
   exit;

}


if($string !~ /.+/){

   print STDERR "INVALID SEARCH STRING\n";
   exit;

}



print STDERR "DIGITS BEFORE SEARCH STRING: ";
$numpre = <STDIN>;
chomp $numpre;

if($numpre !~ /\d+/){
   $numpre = 25;
   print STDERR "DEFAULT SETTING: 25\n";
}

if($numpre < 10){
   $numpre = 10;
   print STDERR "SETTING MUST BE 10 OR LARGER\nNEW SETTING: 10\n";
}

if($numpre >= 51){
   $numpre = 50;
   print STDERR "SETTING MUST BE SMALLER THAN 51\nNEW SETTING: 50\n";
}




print STDERR "DIGITS AFTER SEARCH STRING: ";
$numpost = <STDIN>;
chomp $numpost;

if($numpost !~ /\d+/){
   $numpost = 25;
   print STDERR "DEFAULT SETTING: 25\n";
}

if($numpost < 10){
   $numpost = 10;
   print STDERR "SETTING MUST BE 10 OR LARGER\nNEW SETTING: 10\n";
}

if($numpost >= 51){
   $numpost = 50;
   print STDERR "SETTING MUST BE SMALLER THAN 51\nNEW SETTING: 50\n";
}




$/ = "";

while(<>){

   s/ *\n */ /g;

   while(/$string/ig){

      $count++;

      $key  =  $&;
      $pre  =  substr ($`, -$numpre);
      $post =  substr ($', 0, $numpost);

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

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

   }
}

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




.  merge.pl を実行した結果を見ると,最後の行の @End が前の行と空行で分けられていない。@End とその前のデータが空行で分離されるよう,スクリプトを書き換えなさい。(前回までに学んだことを使って書き換えることができる。)

.  script/PJ.pl を実行しなさい。このスクリプトでは longleg.txt がディレクトリ script と同じ場所にあることを想定しているので,longleg.txt が別のところにあるのなら,それに合うようパスを書き直してから,実行すること。
   スクリプトを見て,今日の授業で学んだことがどう使われているか確認しなさい。(eof は未習。ファイルの終わりに到達したら真となる関数。)