電子書籍の厳選無料作品が豊富!

恐れ入ります。
perlにて、&検索を実行する為に、以下のようにしています。
しかしうまく動作しません。

use CGI

$word = $form->param('word');

open (IN<, "xxx.txt");
$rec=<IN>;
$where="$rec ne '' ";
if($word ne ''){
$word =~ s/ / /g;
@word_array = split(/ / , $word);
foreach (@word_array){
$where .= "and $rec=~/$_/ ";
}
}
if($where){
@rec=split(/,/, $rec);

//省略

xxx.txtを$recに格納して、フォームより送信されてきたスペース区切りの語句を、分割し、各々をマッチさせて検索したいのですが、
どのようにしたらよいでしょうか。よろしくお願いします。

A 回答 (1件)

> if($where){



これは、$whereという変数が示す値が真か偽か、で判定されます。
このプログラムで$whereに代入されるのは「ただの文字列」です。

if( $where ) が if ($rec ne '' and (略) )になって、neによる比較やandに論理計算がされるわけではありません。

eval関数を使うと、文字列をPerlのプログラムとして解釈して
eval($where) が $rec ne '' and (略) になって、neによる比較やandに論理計算がされます。

ただ、現状は $where="$rec ne '' ";の時点で$recが展開されます
$rec='a b c d'
だと eval($where) は
a b c d ne ''
となり、期待通りの動作をしないでしょう。

一つは、エスケープを使うなどして、 $whereを期待通りの式にするものです。
$where="\$rec ne '' ";
にすれば、$recという文字列がそのまま残るので
eval($where) → $rec ne ''
となります。

ただ
$where .= "and $rec=~/$_/ ";

$where .= "and \$rec=~/\$_/ ";
としてしまうと、$_は既に変化しているので期待通りにはならないし、
$where .= "and \$rec=~/$_/ ";
だと、 xxx.txt内の単語が「X/Y」だったりすると
$rec=~/X/Y/
となり文法違反です



もう一つは(こちらを勧めます)
「判定式の文字列」を作るのではなく、判定結果そのものを求めるものです。

ne , andなどは真か偽の値を返します。その値を変数に入れることができます。
$where = ($rec ne '') ;
だと、$recが''なら偽、 $recが''でないなら真が$whereに代入されます。

$where .= "and $rec=~/$_/ ";

$where = $where and ($rec=~/$_/ );
にすれば、それまでの$whereと、 ($rec=~/$_/ ) とのandとなります。

if($where)とすれば、$whereの真偽によって分岐します。



あとは
open (IN<, "xxx.txt");

open (IN, "<xxx.txt");

open (IN,'<', "xxx.txt");
の間違いだとして。

$rec=<IN>;
これは xxx.txt の「最初の1行」を「改行付きで」読みこむことになります。
@rec=split(/,/, $rec);
で、最後の要素には改行文字が付いたままです。
それでよろしいですか?

xxx.txtに日本語等の多バイト文字を使用していませんか?
文字コードによっては、期待通りに動作しないかもしれません。
    • good
    • 0
この回答へのお礼

ありがとうございます。無事に検索が可能になりました。
ご丁寧なご返答ありがとうございました。

お礼日時:2013/03/13 17:30

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!