#!/usr/local/bin/perl # $Id: search-3.cgi,v 1.3 2006/02/04 07:11:40 68user Exp $ use strict; require 'jcode.pl'; my $start_time = times(); $|=1; my @keywords; # 検索対象となるキーワード # 引数解析 foreach ( split(/&/, $ENV{QUERY_STRING}) ){ my ($name, $value) = split(/=/, $_); if ( $name eq 'keyword' ){ $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg; &jcode::convert(\$value, 'euc'); # 前後の空白を削除 my $jisx0208_space = ' '; $value =~ s/^(\s|$jisx0208_space)+//; $value =~ s/(\s|$jisx0208_space)+$//; foreach my $keyword (split(/\++/, $value)){ push(@keywords, $keyword); } } } print "Content-type: text/html; charset=EUC-JP\n\n"; print qq(\n); print "

全文検索その3: 正規表現で全キーワードを一度に検索

\n"; if ( scalar(@keywords) == 0 ){ print "検索キーワードが入力されていません。\n"; print "\n"; exit 1; } printf("

FreeBSD-users-jp を「%s」で検索します。

\n", escape(join(' ', @keywords))); my $freebsd_users_jp_url = 'http://home.jp.freebsd.org/cgi-bin/showmail/FreeBSD-users-jp'; # メールのファイル名を @files に格納 my $maildir = '../../freebsd-users-jp'; opendir(DIR, $maildir); my @files = grep(/^[0-9]+$/, readdir(DIR)); my $found_filenum = 0; # マッチしたファイル数 my $max_found_filenum = 100; # これ以上マッチしたら検索を打ち切る my @tmp_keywords = @keywords; foreach (@tmp_keywords){ $_ = quotemeta($_); $_ = "\$buf =~ m/$_/"; } my $regexps = join(' && ', @tmp_keywords); my $eval_code = < \$b} \@files){ open(IN, "\$maildir/\$filename"); my \$buf = join('', ); close(IN); if ( $regexps ){ matched(\$filename, \$buf, \@keywords); \$found_filenum++; if ( \$found_filenum == \$max_found_filenum ){ last; } } } END ; my $eval_code_for_print = $eval_code; eval $eval_code; print "$@"; print "
eval したコード: "; printf("
%s
", escape($eval_code_for_print)); print "

\n"; print "$found_filenum 件見付かりました。\n"; if ( $found_filenum == $max_found_filenum ){ print "$max_found_filenum 件見つかったので、検索を打ち切りました。"; } print "

\n"; printf("ユーザモード CPU 消費時間: %.2f秒\n", times()-$start_time); print "\n"; exit 0; #---------------------------------------------- sub matched { my ($filename, $buf, @keywords) = @_; my %already_found; print qq($filename
\n); # マッチした行を表示 foreach my $line (split(/\n/, $buf)){ foreach my $keyword (@keywords){ if ( ! defined $already_found{$keyword} && index($line, $keyword) >= 0 ){ printf("     %s
\n", escape($line)); $already_found{$keyword} = 1; # 次の行へ。 last; } } } } #----------------------------------------- sub escape { my ($str) = @_; $str =~ s/&/&/g; $str =~ s//>/g; $str =~ s/ / /g; return $str; }