• ベストアンサー

○○を含まない、という検索方法

CGI RESCUEさんの「簡易データベース v2.1」を利用しています。 http://www.rescue.ne.jp/cgi/database/ 検索方法は if ($name eq $FORM{'name'}) { ; } else { next; } という感じになっています。 これを、「名前に○○と△△と□□を含まないもの残りすべて」とするにはどうしたらよいでしょうか? お願いします。

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

  • ベストアンサー
回答No.6

> 数字が含まれるのが悪いのかと思い、「namea」や「aname」等に変えてみても結果は変わりません。 GETメソッドのパラメータや、ハッシュのキーに数字を含むことについては、問題ありません。 --- 「name」を「name1」に変えたのは、どの箇所の「name」でしょうか。 if ($name =~ /^([\x00-\x7F]|[\x8E\xA1-\xFE][\xA1-\xFE]|\x8F[\xA1-\xFE]{2})*$FORM{'name'}/i) { next; } ひょっとして、↑この $name =~ を $name1 =~ に書き変えた ということはないでしょうか。

master-3rd
質問者

補足

返答ありがとうございます。 修正したのは <!--#include virtual="other.cgi?maker=■&type=all&name=○○" -->   ↓ <!--#include virtual="other.cgi?maker=■&type=all&nameA=○○" --> if ($name =~ /^([\x00-\x7F]|[\x8E\xA1-\xFE][\xA1-\xFE]|\x8F[\xA1-\xFE]{2})*$FORM{'name'}/i) { next; }   ↓ if ($name =~ /^([\x00-\x7F]|[\x8E\xA1-\xFE][\xA1-\xFE]|\x8F[\xA1-\xFE]{2})*$FORM{'nameA'}/i) { next; } (わかりやすいように全角大文字で入力してますが、実際は"a"まはた"1"等で試しました) の2箇所です。 … 今、「確かにこの位置だよな」と考えながら再度サーバにアップして確認してみたところちゃんと予測どおりに動作しました!! 多分なんですけど、昨日サーバにファイルをアップしようとしたら、通信エラーにはなるし、アップにも時間がかかるしと、調子が良くありませんでした。 もしかしたら正常にファイルがアップできていなかったのかもしれません。 アドバイスありがとうございました。

その他の回答 (5)

回答No.5

1. 排除する情報の渡し方について 次の2つの方法のどちらでもよいのではないか、と考えられているようですが、 [1] GETパラメータの値として与える search.cgi?type1=all&type2=all&name1=○○&name2=△△&name3=□□ のようにクライアントから呼び出す [2] CGIプログラム中にハードコーディング(スクリプトに直接記述)する。 [2] の方法だと、変数に日本語が含まれると動作しない場合があります。 CGI RESCUEさんの「簡易データベース」CGI プログラムの文字エンコーディングは、shiftjis で書かれています。 shiftjis日本語文字をハードコーディングすると、なぜ不具合が起こる可能性があるのかは、 「日本語を扱う perlスクリプトはEUC-JPで書く - Perlメモ」 http://www.din.or.jp/~ohzaki/perl.htm#JP_EUC_JP に詳しいです。 ひとまず、[1] のように渡したとしましょう。 これらはCGI 側では、次の3つに格納されます。 $FORM{'name1'} $FORM{'name2'} $FORM{'name3'} データベースファイルを1行ずつ読み込み、この3つが含まれていないかどうかマッチさせていくわけです。 "含まれないものすべて" を抽出したいわけですから、 含まれたらnext とすればよいでしょう。 foreach $num ($FF .. $#BASE) { ... 略 if ($name = ~ /^([\x00-\x7F]|[\x8E\xA1-\xFE][\xA1-\xFE]|\x8F[\xA1-\xFE]{2})*$FORM{'name1'}/i) { next; } if ($name = ~ /^([\x00-\x7F]|[\x8E\xA1-\xFE][\xA1-\xFE]|\x8F[\xA1-\xFE]{2})*$FORM{'name2'}/i) { next; } if ($name = ~ /^([\x00-\x7F]|[\x8E\xA1-\xFE][\xA1-\xFE]|\x8F[\xA1-\xFE]{2})*$FORM{'name3'}/i) { next; } # ここまでたどりついた $name は、「○○と△△と□□を含まない」 }

master-3rd
質問者

補足

返事が遅くなってすみません。 どうしても出来なかった為、返答が遅れました。 さて、出来なかった理由ですが… <!--#include virtual="other.cgi?maker=■&type=all&name=○○" --> で呼び出し、 if ($FORM{'name'} ne '') { if ($name =~ /^([\x00-\x7F]|[\x8E\xA1-\xFE][\xA1-\xFE]|\x8F[\xA1-\xFE]{2})*$FORM{'name'}/i) { next; } else { ; } } で検索すると、無事「○○」を削除した結果が表示されました。 しかし、「name」は別に利用しているので、「name1」に変えて再度やってみました。 すると、全部表示してしまいます。(○○を含んでしまう) 数字が含まれるのが悪いのかと思い、「namea」や「aname」等に変えてみても結果は変わりません。 これはどこが悪いのでしょうか?デコード部分? どこかに「$name1=$FORM{'name1'}」等を指定してあげる必要があるのでしょうか? ---------------------------------- #■入力 if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } if ($buffer eq "") { &error('エラー','使い方が間違っています.'); } @pairs = split(/&/,$buffer); foreach $pair (@pairs) { ($name,$value) = split(/=/, $pair); $name2 = $name; $value2 = $value; $FORM2{$name} = $value; $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; &jcode'convert(*value,'euc'); $value =~ s/</&lt;/g; $value =~ s/>/&gt;/g; $value =~ s/\n//g; $value =~ s/\r//g; $value =~ s/\t//g; $value =~ s/\,//g; #フォーム変数へ $FORM{$name} = $value; }

回答No.4

「残りすべて」の表示もSSIで呼び出すのでしょうか? だとすると、以下のような1行が追加されるのかな? <!--#include virtual="search.cgi?type1=all&type2=all&name1=○○&name2=△△&name3=□□" -->

master-3rd
質問者

補足

返答ありがとうございます。 ><!--#include virtual="search.cgi?type1=all&type2=all&name1=○○&name2=△△&name3=□□" --> そんな感じです。 ただ、排除する情報は3つ以上にはならないので、変数として渡してもいいですし、直接CGI内で排除してもいいのではないかと思っていますが… よろしくお願いします。

回答No.3

デフォルトの検索フォームは、 「フォームに入力された名前に一致する」データを検索します。 検索条件入力フォーム (index.html ) は、 複数の「含まれない名前」○○と△△と□□を入力して送信できるようになっていません。 1. まず、この含まれない名前をPOST送信できるようにフォームを変更する必要があります。 2. 次に、POST された「○○と△△と□□」をCGI側で受け取って処理できるようにします。 仮に、含まれたくない名前を、CGI側で、$FORM{"not_name"} に空白区切りで受け取れるものとします。 $FORM{"not_name"} に 'Bob Tom Mary' が格納されたとして、 whileループの前に、 my %not_name = map { $_ => 1 } split /\s+/, $FORM{"not_name"}; として、 ( 'Bob' => 1, 'Tom' => 1, 'Maary' => 1 ) というハッシュを作ります。 if ( $not_name{$name} ) { next; } として、ハッシュの値に、NGな名前が存在すれば、next とすればよいでしょう。

master-3rd
質問者

補足

皆さん返答ありがとうございます。 色々と考えてやってみたのですが、うまく出来ません。 まず、検索用プログラムの利用方法ですが、「リストの中の必要な情報のみをSSIで表示する」ということに利用しています。 <!--#include virtual="search.cgi?type1=all&type2=all&name=○○" --> <!--#include virtual="search.cgi?type1=all&type2=all&name=△△" --> <!--#include virtual="search.cgi?type1=all&type2=all&name=□□" --> という感じで、リストからいくつかの名前だけを抜き出して利用しています。 これに一致しないその他のリストを表示させたいです。 しかし、ここで問題が… nameのところは if ($name = ~ /^([\x00-\x7F]|[\x8E\xA1-\xFE][\xA1-\xFE]|\x8F[\xA1-\xFE]{2})*$FORM{'name'}/i) { ; } else { next; } で検索していました。 そうすると、もちろんですが、「○○-1」等も○○のところに表示されますよね。 なので、「○○-1」は”残りすべて”の所には表示させないようにしないといけません。 皆さんから教えていただいた方法では、「○○-1」も”残りすべて”の所に表示してしまいますよね? これを回避するにはどのようにしたらよいでしょうか? 再度よろしくお願いします。

  • namiri_e
  • ベストアンサー率37% (37/98)
回答No.2

○○、△△、□□などの除外するものがこれ以上に増えていくのなら配列にするのが良いですね。 next;があるので何かのループの中ですね。 (データファイルを読み込むループでしょうか) まずループの外でフォームから送信されたデータについて、先に除外するかどうか判別しておきます。 @jogai = ('○○','△△','□□','以下同様に'); $flag = 0; foreach (@jogai) { if ($FORM{'name'} =~ m/$_/) { $flag = 1; last; } } このforeach文でフォームから送信されたデータに該当の文字を含むものにフラグを立てておきます。 あとは該当部分をフラグの有無を判別するように少し書き換えればいけると思います。 if (!$flag && $name eq $FORM{'name'}) { ; } else { next; } 「$●● =~ m/■■/」の書き方の詳細は「正規表現」で検索してみてください。

  • Suzi
  • ベストアンサー率38% (130/334)
回答No.1

○○と△△と□□の3つが必ず含まれないのなら、 if($FORM{'name'} !~ /○○/ && $FORM{'name'} !~ /△△/ && $FORM{'name'} !~ /□□/){ ・・・・ とかでは。 ○○、△△、□□が日本語でかつShift_jisだと上手くヒットしない場合があるので、EUCの方が良いかもしれません。

関連するQ&A