• ベストアンサー

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

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

  • shevy
  • お礼率67% (703/1046)
  • CGI
  • 回答数6
  • ありがとう数6

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

  • ベストアンサー
  • 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

  • perl 特定の文字列をdatファイルから抽出したいです。

    ホームページ上の日記を作成中です。 わからないことがあったのでお助けください。 たとえば、nikki.cgiファイルの中に、 20030426Sat という文字列が格納されている変数$valueが 存在したとします。 その変数$valueの値を使用して、CGIファイルは、 nikki.datの中から、その 20030426Satが含まれている一行を探し出そうとするという作りにしたいと思っています。 nikki.datの構成は、 一日ごとのコンテンツを改行コードで区切ることにします。 一行分の内容は、 例えば、 20030426Sat,17:32,今日はいい天気だった というように、日付、時間、日記本文というようにしたいと思っています。 長くなりましたが、この日付の文字列をnikki.datファイルの中から見つけ出して、その一行分を抽出するには、どのような関数を使えばよいのでしょうか? また、nikki.datファイルに日記を書き込む処理を別途させなくてはならないので、ちょっと私の考えは非効率かと思っていたりします。 日記作製の際のCGIの効率的な利用方法をご存知でしたら教えてください。 一応カレンダーは完成しています。カレンダーをクリックするとその日の日記が表示されるという仕組みです。 アドバイスをお願いします。

    • ベストアンサー
    • CGI
  • perlで重複をさせない処理

    perlでプログラムを書いています。躓いたところが あるのでどうかご協力おねがいします。 a.datとa.cgiがあるとします。 a.datには、 a b c b a とデータが入っています。 そこで、datファイルを見てa、b、cというそれぞれ タイトルが入ったテーブルを自動的に作成させたいです。 (datの中身は増えていくので種類が増えたらテーブルも 増えます。重複はまとめて1個にしたいです) まずaというテーブル作成→改行→bというテーブル作成 →改行・・・といった感じです。(dat内でアルファベットで昇順) ファイル操作の追加モードみたいな感じです。 結構考えたのですがコードが思いつかずここにきました。 どうか、考え方だけでもいいのでよろしくおねがいします。

    • ベストアンサー
    • CGI
  • Perlでのマッチング処理について

    検索CGIを作成しているのですが、検索文字に「ー」(-ハイフンではありません。日本語入力の言葉を伸ばすやつです。”サーバ”とか。)が入った文字を指定し、POSTするとServerErrorになってしまいます。サーバはレンタルものなので原因が分からず途方にくれています。どなたかPerlに詳しい方、ぜひよいアドバイスを下さい。ちなみに処理は下記のように行っています。 (1)検索する元のデータはsjisである。  ↓ (2)ブラウザのフォームから、検索したいデータがsjisでPOSTされる。  ↓ (3)ReadParseにてデータを変数へ取り込む。(cgi-lib.pl使用)  ↓ (4)CGIにて、POSTされたデータをeucへ変換。(jcode.pl使用)  ↓ (5)検索する元のデータが入ったファイルをオープン。  ↓ (6)ファイルから1行づつ読み込み変数へ格納。  ↓ (7)変数へ格納したデータをeucへ変換。  ↓ (8)if (${POSTされたデータ} =~ /${ファイルから読み込んだデータ}/)といった形でマッチング処理  ↓ (9)ファイルをクローズし、マッチングしたデータをsjisで結果表示。 ※まだデバッグ途中なのですが、とりあえず今判明しているのは 『インターネット』などというふうに、『ー』がキーに入るとエラーになります。 どなたかよろしくお願いします。

    • ベストアンサー
    • Perl
  • perlの構文間違いについて

    以下のような、perlの構文で$infoをmyスコープで宣言しつつ、$datという変数が真なら$infoに$datが入ることを期待しているのですが、まちがっているのでしょうか? my $info = $dat if ($dat); よろしくお願いします。

    • ベストアンサー
    • Perl
  • Perlの処理について

    Perlの処理について分からない事があります。 ご存知の方アドバイスを頂けますよう よろしくお願い致します。 (分からない処理内容) 下記処理内容で、$hensuがどういう時に &errs()をコールするのか分かりません。 アドバイスを頂けますよう よろしくお願い致します。 $hensuは、変数です。 &errs()は、個別で作成した関数です。 $Errorpathは、Errorファイル名です。 ( $hensu !~ /^( | |\\n)*$/ ) || ( &errs( 11, $Errorpath ) and exit );

    • ベストアンサー
    • Perl
  • Perl 掲示板 初心者

    初の投稿で大雑把な質問失礼致します。 (1)目的・・・ホームページに掲示板を設置したい (2)言語・・・Perl (3)文字コード・・・UTF8(Encode) Perlでメールフォームは作ることはできました。 メールに関しては、ネットサーフィンでなんとか完成したのですが、 掲示板は、たくさんでてくるも、どれもうまいこと動作しません・・・ http://webings.net/perl/boardimg1/ ここのサイトのようにしたいのですが、 コピペで貼付けし、サーバーに送り実行すると 書込ファイルが開きませんと表示されます まずファイルの読込から躓いていて、先に進みません・・・ サーバー側に index.html----cgi----bbs.pl----dat----boardimg-----jpg,png,gif等 |-----boardimg.dat このようなフォルダ構造ではないのでしょうか? パーミッションは bbs.pl→777 boardimg.dat→666 そこで、教えて頂きたいのが (1)このサイトで、どう改善すればいいのか・・(すごく大雑把申し訳ないです) (2)初心者でもわかるようなサイト (3)掲示板の仕組み(ファイルの読込、書込について) また、このサイトの掲示板では、Perl内でHTMLが記述されてますが、 ホームページのformからCGI.pmでデータの受け渡し にするほうがいいのでしょうか?

  • perlで

    $xが1に等しかったら ブラウザクライアントに 1.html を送り表示させ $xが0に等しかったら ブラウザクライアントに 0.html 送り表示させる ようにCGIファイルを作ることはできるでしょうか? ($x例えばはPOSTで受け取った変数です) 1.htmlや0.htmlを読み込みprintで一行ずつ書いていくことしかできないのでしょうか?

    • ベストアンサー
    • Perl
  • Perlでテキストファイルの処理方法

    Perlでファイル入力は 下記のように記述します open (IN,"myInput.txt"); $lineno = -1; while (<IN>) {  $lineno = $lineno + 1;  @lines_org[$lineno] = $_;  #print lines_org[$lineno];  #print $_,"\n";  } これで一行づつ入力できます ここで質問したいのは 入力ファイルに改行コードがないため 処理できないと思うのですが 一行づつ入力ではなく、1文字づつ入力する 入力方法はPerlにはないのでしょうか ちなみに入力ファイルは数メガある大きなファイル です よろしくおねがいします

    • ベストアンサー
    • Perl
  • perlについて

    perlのなかにリファレンスの機能がありますが%hashって ハッシュがじぜんに定義されている状態で $fields=\%hash; $form{field}=$fields; $form{field}=$fields; $item=\%form; という構造の$item変数があります。 一行で$itemから%hashを呼び出す時の書き方 を教えてください。

    • ベストアンサー
    • Perl
  • perl CGIが開くと勝手に処理してしまうのを防ぎたい

    BBSを作成中で、そのBBSに記事ナンバーをつけようと奮闘中です。そこで質問があります。Flashを使って作製していますが、CGIの質問は非常に稚拙だと思いますので、お助けください。 記事のナンバーカウントの値がアップする仕組みをCGIファイルに 組み込んだのですが、書き込みボタンが押されていないのに、 最初にページを開いた瞬間に、カウントがアップしてしまう状態になってしまっています。それ以後は、ページを閉じない限りは、書き込みボタンが押されるたびにカウントの値は1ずつきちんと増えていきます。 要するに、ページを開いたときにカウントが1増えるのを防ぎたいのです。 ちょっとうまく伝えにくいのですが、 以下のような仕組みになります。 count.datファイルの中の数値が一つずつあがっていくようになっています。 #----- ファイルを読み込む $countfile = "./count.dat"; #-----カウントの値の読み込み open(COM,"$countfile"); $cnt=<COM>; close(COM); #-----カウントの値に1プラスする $cnt++; open(COM,">$countfile"); print COM $cnt; close(COM); と、以上のような単純な仕組みなのですが、 最後の「カウントの値に1プラスする」という処理が勝手に実行されてしまいます。 CGIファイルの一番下にカウントの値を1プラスする処理を実行するスクリプトを置いたのですが、 最初に実行されてしまうようです。 宜しくお願い致します。

    • ベストアンサー
    • CGI