サイト内検索
サイト内検索は、同ディレクトリ内にあるファイルから検索条件である文字列が見つかった場合に
そのURLを返すスクリプトです。
#!/usr/bin/perl
# 検索の対象とする拡張子
@SEARCH = ('html', 'htm', 'shtml');
# デコード処理
if($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $query, $ENV{'CONTENT_LENGTH'});
} else {
$query = $ENV{'QUERY_STRING'};
}
@args = split(/&/, $query);
foreach $i (@args) {
($name, $val) = split(/=/, $i);
$name =~ tr/+/ /;
$name =~ s/%([0-9a-fA-F]{2})/pack('C', hex($1))/eg;
$val =~ tr/+/ /;
$val =~ s/%([0-9a-fA-F]{2})/pack('C', hex($1))/eg;
$in{$name} = $val;
}
# ワードが入力されていないなら
unless($in{'word'}) {
print "Content-type: text/html\n\n";
print "検索ワードを入力してください!\n";
exit;
}
# 全角空白を半角空白に変換
$in{'word'} =~ s/ / /g;
# 検索ワードを分割
@word = split(/ /, $in{'word'});
opendir(DIR, "./");
while($file = readdir(DIR)) {
my($f) = 0;
# 検索対象の拡張子かどうか
foreach(@SEARCH) {
$f = 1 if($file =~ /$_$/);
}
# 検索対象の拡張子でないなら
next unless($f);
$f = 0;
open(DATA, "< $file");
my(@line) = <DATA>;
close(DATA);
# 検索開始
foreach $w (@word) {
foreach $l (@line) {
# 検索ワードが一致したなら
if($l =~ /$w/) {
$f++;
last;
}
}
}
# 検索ワードがすべて一致したなら
if($f == @word) {
# URLを配列へ追加
push(@url, $file);
}
}
closedir(DIR);
# 配列の要素数取得
$n = @url;
print "Content-type: text/html\n\n";
if($n) {
# 検索に引っかかったなら
foreach(@url) {
print "・ <a href=\"$_\">$_</a>\n<br>";
}
} else {
# 検索に引っかからなかったら
print "一致するワードはありませんでした。\n";
}
今回のサイト内検索は、同一ディレクトリのファイルのみ検索を行っています。
今回の仕様では移動先のどこに検索ワードがあるのかがわかりません。
検索ワードを複数に対応させるためには、検索ワードを半角空白で区切ります。
このとき、ユーザーが全角の空白を入れることを想定して、全角空白を半角空白に変換する処理も入れておきます。
検索するためには、対象ファイルを一つ一つ開いて、そこから検索ワードと比較させていきます。
検索ワードが複数ある場合はすべて一致した場合のみ検索結果へ反映させる必要があります。
そのため、検索ワードの数と一致した数が同じな場合に検索に引っかかったと判断します。
なお、配列の要素数を取得する場合は、"$num = @配列名;" とすれば可能です。
