やっと,最終章にたどりつきましたよ.最後はevalの使い方,map,grep,あと,スライシングなどがテーマ.
1. 単語のリストをファイルから読み込み,ユーザが入力した正規表現をマッチさせ結果を表示する
以外に単純そうな問題ですが,これを今までの知識を工夫してうまく書いてみよう,という趣旨だと思う.
適当な入力ファイルがないんですが,とりあえず以下のを使いました.
haruhi mikuru yuki yuki haruhi kyon haruhi mikuru
ちょっと単純すぎる気もするがまぁいいや.
このファイルを配列に読み込んで,一つずつマッチさせる感じですね.マッチした単語を抜き出すのにはgrepを使います.さらに,入力された正規表現のエラー処理にevalを使用.以下にコード.
#!/usr/bin/env perl -w
use strict;
# 入力ファイルの指定
my $infile = 'words.txt';
open IN, $infile or die "cannot open $infile: $!";
# リストコンテキストで一気に読み込む
chomp(my @words = <IN>);
close IN;
while (1) { # 空行の入力があるまで
# 正規表現の入力を受け付ける
print "input your regext: ";
chomp(my $regex = <STDIN>);
last if $regex =~ /^\s*$/; # 空行ならループをぬける
my @matches;
eval { # evalでエラーをキャッチ
# grep を使ってマッチした単語を抜き出す
@matches = grep /$regex/, @words;
};
if ($@) { # エラーが起きた時
print "error occured: $@";
next;
}
# 結果を表示
my $count = $#matches + 1;
print "$count matches: \n";
for my $word (@matches) {
print "$word\n";
}
print '-'x10,"\n";
}
print "done\n";
さて,さて,実行してみますよ.
$ ./ex17.pl input you regext: haruhi # 普通の文字列で 3 matches: haruhi haruhi haruhi ---------- input you regext: ^[hy] # 当然正規表現つかえます 5 matches: haruhi yuki yuki haruhi haruhi ---------- input you regext: (mikuru # 正規表現に問題があると error occured: Unmatched ( in regex; marked by <-- HERE in m/( <-- HERE mikuru/ at ./ex17.pl line 23, <STDIN> line 3. input you regext: done
はい,できましたー!.解答では,さらにforのかわりにmapを使ってきれいに出力していました.17章は1問だけであっさり終了ですね.
というわけで,初めてのPerlの練習もんだいついにコンプリート.これ,ちょっとまとめたエントリーを書くかな.