• ベストアンサー

正規表現での検索がうまくいきません…

質問させて下さい。 WindowsにてAtivePerlの5.8.6.811を使っています。 サーバはAnHttpdです。 htmlの文章ファイルを読み込んで、空白行で区切ってリストに読み込み、そのリストを配列ごとに正規表現で検索して、マッチしたものだけをhtmlで表示しようとしています。 ところが、検索結果にどうにも変な時があります。 少し試したところ、「ゲーム」「ラッキー」などの「ー」が入る文字を検索しようとすると、全く処理をしてくれないのです。 その上、そのパターンマッチ検索のスクリプトより下に書いた行が全て実行されなくなってしまいます。 Shift-JISで書いているので、ダメ文字の類なのかとも思い、シングルクォートで囲ったり、「ー」の後に\をいれてみたりもしましたが、変化ありません(十や表はこれでうまくいきました…)。 また、それ以外にも、「スイス」などという、絶対に書かれていない単語で検索しても、検索されてしまう配列があったりします。 これに至っては完全に謎です…。 分かる方がいらしたら、どうかよろしくお願いします。

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

  • ベストアンサー
  • php504
  • ベストアンサー率42% (926/2160)
回答No.2

正規表現マッチにiをつけると スとベ イとツ の区別がつかなくなります ”ベツベ”、”ベイス”、”スイベ”などにもマッチすることになります。 あとquotemeta()の代わりに f($_ =~ m/"\Q$kensaku\E"/im){print "$_","\n\n";} という書き方も出来ます。

yoshinori0830
質問者

お礼

ご回答ありがとうございます! 大変参考になりました。 確かに、スイベでもヒットします…。そしてベイスという文字が検索された配列の中にありました。 iを付けると、そんな落とし穴もあったのですね…。 回避する方法はなさそうですね… でも、原因が分かっただけでもすっきりしました。 どうもありがとうござました!

その他の回答 (3)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

#テストスクリプトを書いてみました。 use Encode; #$buffer="search=%E3%82%B9%E3%82%A4%E3%82%B9";# search="スイス" by charset="UTF-8" $buffer="search=%E3%82%B2%E3%83%BC%E3%83%A0";#search="ゲーム" my @pairs = split(/&/,$buffer); foreach $pair (@pairs){ my($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $kensaku = $value;#quotemeta($value);←特別必要ない } #文字コード指定をして内部コードに変換 #$kensaku=Encode::decode("Shift_JIS",$kensaku);#Shift_JISの場合 $kensaku=Encode::decode("UTF-8",$kensaku);#UTF-8の場合 #binmode STDOUT,":encoding(shiftjis)";#出力の文字コードの指定、不要な場合は不要 open DB, "<:encoding(UTF-8)","(songbook.html";#文字コードを指定して読み込む @db = <DB>; $db = <<"EOL"; @db EOL close DB; @db2 = split(/\n \n/,$db); foreach (@db2){ if($_ =~ m/$kensaku/im){print "$_\n\n";} }

  • php504
  • ベストアンサー率42% (926/2160)
回答No.3

use encoding "shiftjis"; で回避できませんか

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

どんなふうに書いていますか? マルチバイト文字を扱う場合は、 encoding 指定をするとか、 Encode::decode とかで内部文字列表現に変えてやらなくちゃ生データ文字列のままだと正しく動作しませんよ。

yoshinori0830
質問者

お礼

ご回答ありがとうございます! ですが、すみません、quotemeta関数というものを使ってみたら、「ー」を使った時のエラーの方は解決しました。 あとは、「スイス」で検索されてしまう配列がある問題だけです…。 色々、対照実験のように文字を変えてやっていますが、「スキス」「スイカ」「ザイス」などでは検索されません。なのに「スイス」だけはどうやっても検索されてしまいます…。 恥ずかしながら参考までにスクリプトをのせます…。とても汚いですがすいません…。 read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); print <<"EOM"; Content-type: text/html\n\n <html><head><style type="text/css"><!--a:hover{color:eeeeee;background-color:#b2946c}.1{border-bottom-style:solid;color=tan;width=100%}A { text-decoration: none; }--></style></head><body bgcolor="#eeeeee" link="#b2946c" vlink="#aaaaaa" leftmargin="30"><font color=52340c><pre> EOM my @pairs = split(/&/,$buffer); foreach $pair (@pairs){ my($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $kensaku = quotemeta($value); } open DB, "<(songbook.html"; @db = <DB>; $db = <<"EOL"; @db EOL @db2 = split(/\n \n/,$db); foreach $_(@db2){ if($_ =~ m/$kensaku/im){print "$_","\n\n";} } print <<"EOM"; $kensaku <a href="(songbook.html">戻る</a> </body></html> EOM }

yoshinori0830
質問者

補足

不要な行ものせてしまったので、こちらでお願いします。 read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); print <<"EOM"; Content-type: text/html\n\n <html><head><style type="text/css"><!--a:hover{color:eeeeee;background-color:#b2946c}.1{border-bottom-style:solid;color=tan;width=100%}A { text-decoration: none; }--></style></head><body bgcolor="#eeeeee" link="#b2946c" vlink="#aaaaaa" leftmargin="30"><font color=52340c><pre> EOM my @pairs = split(/&/,$buffer); foreach $pair (@pairs){ my($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $kensaku = quotemeta($value); } open DB, "<(songbook.html"; @db = <DB>; $db = <<"EOL"; @db EOL @db2 = split(/\n \n/,$db); foreach (@db2){ if($_ =~ m/$kensaku/im){print "$_","\n\n";} } print <<"EOM"; <a href="(songbook.html">戻る</a> </body></html> EOM

関連するQ&A