第17章 上級テクニック 練習問題

やっと,最終章にたどりつきましたよ.最後は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の練習もんだいついにコンプリート.これ,ちょっとまとめたエントリーを書くかな.