• ベストアンサー

perl これは前文検索システムの処理に近いでしょうか?

先日、カレンダー日記のperlによるスクリプト構造について質問させていただいたのですが、 今回の質問は、その処理をする上で知っておくべき処理は何なのかを教えていただきたく、質問させて頂きました。 perlの参考書は多いですが、以下の処理をズバリ書いてくれている書籍はないので、以下の処理を実現するなら、このような処理を書いている本を買えばいいというような助言をお願いします。書籍名でも助かります。 以下、処理の内容 カレンダー日記の構造は、 日付けをクリックすると、例えば本日なら、20030427という値を変数に格納して、 nikki.cgiファイルに飛ばすようにしようと思っています。 nikki.cgiファイルは、受け取った変数を記憶して、 nikki.datファイルからその、20030427で始まる一行を探すようにします。 nikki.datファイルの中身は、一つの改行コードが出てくるまでを一日分とします。 たとえば、 20030427,4月27日(土),22:14,今日も快晴だった というような一行が、一日分です。 こうした一行が何行も書かれているnikki.datファイルの中からクリックされた日付けを見つけ出して、返すという仕組みです。 データベース的な処理?のようなので、どういった知識をつければ、より今後の勉強に役に立つか、そういったことを知りたくなったので、アドバイスを頂きたいと思います。 書店で見たperlの本のサンプルは、たいてい、 掲示板、チャット、アクセスカウンタ、全文検索、などばかりで、 カレンダー日記というのはなかったもので、果たしてどういう処理の勉強から取り組めばいいのか、そこに立ち返ろうと思っています。 全文検索あたりがnikki.datファイルの中から一行を選び出すという意味で、 似ているかなと思ったのでタイトルにしてみましたが、実際のところ、どうでしょうか。 宜しくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • jubay
  • ベストアンサー率30% (3/10)
回答No.5

データベースを使うのが一番良い方法だと思いますが、 レンタルサーバなどでは使えなかったりします。 バージョン5以降のPERLならデータ構造をサポートして いるので、 例えば、nikki.datがあるとして、 ---------------------- 030424,0830,4/24-8:30,data1 030425,1230,4/25-12:30,data2 030426,0920,4/26-9:20,data3 030426,1030,4/26-10:30,data4 030426,1040,4/26-10:40,data5 030427,1500,4/27-15:00,data6 ---------------------- 上記のデータから4/26分のデータを取り出には、 $request = '030426'; open (FILE,"<nikki.dat") or die; while (<FILE>){ chomp; ($date,$time,$hizuke,$content) = split (/,/); $db{$date}{$time} = "$hizuke,$content"; } close FILE; $c = 0; foreach $key (sort keys %{$db{$request}}){ ($hizuke,$content) = split (/,/, $db{$request}{$key}); print "$hizuke $content\n"; $c++; } print "none data\n" if ($c == 0); のような方法はどうでしょうか。 ただし、この方法だと、データ数が多くなると効率が 悪くなるので、nikki_dataフォルダを作って、その中 に一ヶ月分ずつ(例:0302.dat,0303.dat,0304.dat)の ファイルを作ってやる方がいいと思います。

shevy
質問者

お礼

たしかにデータがおおくなると大変そうですが、 ご指摘の通り、月ごとにいれていこうと思います。 ありがとうございました。

その他の回答 (5)

  • jubay
  • ベストアンサー率30% (3/10)
回答No.6

すみません。#5の修整です。 open (FILE,"<nikki.dat") or die; while (<FILE>){ chomp; $a = 0; ($date,$time,$hizuke,$content) = split (/,/); while ($db{$date}{$time}[$a]){ $a++; } $db{$date}{$time}[$a] = "$hizuke,$content"; } close FILE; $c = 0; foreach $key (sort keys %{$db{$request}}){ $a = 0; while ($db{$request}{$key}[$a]){ ($hizuke,$content) = split (/,/, $db{$request}{$key}[$a]); print "$hizuke $content\n"; $a++; } $c++; } print "none data\n" if ($c == 0); #5だと、同じ時間のデータが二つ以上あった場合、 一つしか表示されません。

shevy
質問者

お礼

ありがとうございます。 ご丁寧にスクリプトまで組んでくださいまして、本当にありがとうございました。 じっくり解析させていただき、 自分のコーディングに活かさせていただきます。 ありがとうございました!

  • ikspiari
  • ベストアンサー率48% (29/60)
回答No.4

Perl のみの処理でしたら No.2 さんの回答が最もスタンダードな方法だと思いますよ。 先日の split 関数書き方違ってましたね、すみません。 最近はあんまり Perl 使わないので・・・ DBM は、dbmopen と dbmclose を使うだけですよ。 その中でデータを連想配列として扱えます。 ただ、使える文字数に制限があった気がします。 結論から申しますとテキストにデータを書き込んでいくのでしたら、それを読み込んで処理する以外に方法はないと思いますが・・・

shevy
質問者

お礼

ありがとうございます。 dbmについての本を見かけたことがあるので、 そちらも考慮して考えていこうと思います。 それにしても今日は本当に一日どっぷりと スクリプトとにらめっこしていました。 非常に面白いですが、大変です。 ありがとうございました。

  • ikspiari
  • ベストアンサー率48% (29/60)
回答No.3

全文検索とは違うと思いますよ。 今回の場合、特定のカラムからレコードを取り出すという考えでいくと SQL を使うと楽でしょう。 例えば、テーブル名が「diary」で日付のカラム名が「date」だと仮定すると、 select * from diary from date = '20030427'; で、該当するレコードが全て返されます。 フリーのデータベースで有名なのは PostgreSQL と MySQL ですね。 ただし、これを導入する技術と SQL や日常の管理方法も覚えないといけません。 また、Perl から扱う為には DBI などのモジュールも必要です。 上記 SQL 文は最も簡単なものですが、データベースも、テーブルの正規化やインデックスのはり方、そして SQL の発行方法が違うだけで処理速度が大幅に変わります。 Perl はテキスト処理が得意な言語なので、データサイズが小さければデータベースを導入するまでの必要はないと思います。 日付がユニークな値でしたら DBM とか使ってみたらどうでしょうか? 簡易データベースみたいなもので、考え方は連想配列と同じです。

shevy
質問者

お礼

ありがとうございます。 SQLですか、聞いたことはあるんですが、 Perlもままならないのに、さらに他言語になってしまうとちょっと頭が痛いですが、 やはり日記検索になるとこうした処理が必要になっちゃうんですよね。 Perlをまずはもっと鍛えたいので、Perlのみで考えると、Perlの処理で一番似ているのは、 読み込み、表示の意味では掲示板に近いと思いますが、 ネックとなるのは、やはり特定の日付けの検索ということになりますよね。 DBMというのは、書店でちらりと見たりしましたが、 難しいんでしょうか。連想配列の意味ならなんとかわかるので、まだいけるかなと思ったりします。 ですが、あえてPerlにこだわるとしてアドバイスをいただけないでしょうか。 書店にて似ている処理について書かれている書籍を本日買い求めようと思っています。

  • mohao
  • ベストアンサー率15% (10/63)
回答No.2

データが以下のように','(カンマ)区切りであった場合, 20030427,4月27日(土),22:14,今日も快晴だった データファイルを一行ずつ読み込んで,','で分割して配列に放り込みます。で,検索対象と$dateが一致していたら,何らかの処理をし,一致していなかったら,次へ,・・・でファイルを全て読み込むまで繰り返し。という処理になると思います。 $date='20030427'; open FILE,'nikki.dat'; while (<FILE>) {   chomp($_);   @data=split(/,/,$_);   if ($data[0] eq $date) {     //該当する     処理   } else {     //該当しない     next;   } } close FILE; のようなかんじで。

shevy
質問者

お礼

ありがとうございます。 シンプルにまとまっていて、理解しやすかったです。 じっくりとくみ上げようと思います。 ありがとうございました。

  • the845t
  • ベストアンサー率33% (246/743)
回答No.1

@thatday = grep(/^20030427\,$/,@dat); かな? 全文検索などの知識はまったくありませんので、 もっと効率良い、または安全な方法があるのかもしれません。

shevy
質問者

お礼

ありがとうございます。 勉強いたします。

関連するQ&A