辞書を片手に~PatternResponderの作成(1) | Pythonでなんか作ってみる

辞書を片手に~PatternResponderの作成(1)

さて、どうやらアメブロの重さも改善されたようなので、続きです。

しかし、間を開けすぎてやる気を取り戻すのに時間が・・・。

まぁ、嫌々やっても仕方ないのですが、のんびり始めることにしましょう。



では、前回からのToDoで残っているもの。


ToDoリスト

・正規表現を使ってパターンに反応するResponder


タイトルどおり、PatternResponderという名前にする。教科書(『恋するプログラム―Rubyでつくる人工無脳 』)でのクラス名そのままだが。そういえば、最近の記事もこの本の章題をそのまま使っていたりするが、良いのだろうか?引用の要件は満たしていると思うのだが。


教科書の該当章はCHAPTER 5-4になるが、ここではそのPatternResponderの仕様について4つにまとめているので、ToDoに追加する。仕様がそのままUnitTestに出来るとは限らないが、テストの出所としては間違いない。


ToDoリスト

・正規表現を使ってパターンに反応するResponder(以下の仕様を満たす)

・パターン辞書の先頭行からパターンマッチを行い、マッチした行の応答例をもとに応答メッセージを作る

・1つのパターンに対して応答例は「|」で区切って複数設定でき、いずれかがランダムに選択される

・マッチするパターンがなかったときは、ランダム辞書からランダムに選択した応答を返す

・応答例の中に「%match」という文字列があれば、パターンにマッチした文字列と置き換えられる


いきなりToDoが難解になってしまう。しかも、ランダムが2箇所に出てきて、テストが難しそうだ。

この章でランダムを誤魔化すことが必要になりそうに思うが、とりあえず考えないことにする。


この中で、まずは手をつけられそうなのは、パターン辞書からの読み込みだろう。少なくとも、既にランダム辞書を読み込むためのコードは「辞書はファイル」に書いていたはず。


教科書は、Rubyを題材にしているため、当然実装にはRubyを使用するわけだが、Rubyの文字列オブジェクトには、『引数として渡された文字列を正規表現として、自分自身に対してパターンマッチを行う』matchというメソッドがあるらしい。


if m = input.match(re)

処理A(応答メッセージを作る)

end


この式では、inputがユーザからのメッセージ文字列で、mにはreで渡された正規表現とマッチした結果が入るそうだ。

Javaの文字列オブジェクトには、そんなメソッドは無いため、正規表現オブジェクトに対して文字列を渡して、正規表現に文字列がマッチするかどうかをチェックするのが自然だろう。


private boolean match(String targetString, String pattern) {
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(targetString);

return m.matches();
}


このメソッドでは、pが正規表現のパターンを示すオブジェクト、mがマッチ結果を示すオブジェクトのはず。

これを辞書ファイルの各行で繰り返せばいいはずだ。

つまり2番目のToDoは、次の小さなToDoに分割できる。


ToDoリスト

・パターン辞書の先頭行からパターンマッチを行い、マッチした行の応答例をもとに応答メッセージを作る

・パターン辞書から正規表現のパターンオブジェクトのグループを作る

・パターン辞書から応答例のグループを作る

・パターンオブジェクトのグループに対して順番に入力文字列がマッチするか確認し、対応する応答例を求める


ここまで考えて随分設計をしている(実装を考えている)という気がしてきた。


本当にテストに駆動させているのだろうか?


わからないが、「パターン辞書から正規表現のパターンオブジェクトのグループを作る」をやってみる。