Shift-JISからEUCにすると文字化け

[上に] [前に] [次に]
ミント 1999/10/04(月) 12:07:20
データ検索CGI(perl,unix)を使っているのですが
文字化けを防止するため、スクリプトや文字変換法、
データファイルをShift-JISコードからEUCコードに変えたところ、Shift-JIS時にはなかった文字化けが出てくるようになりました。

データファイル$fileは「,」で区切ったCSV形式データです。
検索部分は以下の通りです。

$search = $FORM{'word'};#検索語(複数語をスペースで区切って入力可)
$select = $FORM{'select'};#andかorで選択

$search =~ s/ / /g;$search =~ s/\t/ /g;
@pairs = split(/ /,$search);
open(DB,"$file");
seek(DB,0,0);
while ($line=<DB>){
$flag=0;
foreach $pair (@pairs){
if( (index($line,$pair)>=0)  ){
$flag=1;
last if  ($select eq 'or');
}else{
if($select eq 'and'){$flag=0; last; }
}
}
push(@newlines,$line) if ($flag);
}
close(DB);

試した限りでは、

「東京」→「ナ・・」
「江戸川」→「江戸旋宗」
「川上」→「旋昴」

のようになります。
また、「江戸」と「江戸 」で化け方が変わるので、
文字列の最後に問題があるような気がしています。
これはどうしようもないのでしょうか?

IE4(Win95)を使っているので、それが原因かと思い、
フォームページをEUCやShift-JISなどに変えてみてましたが、
同じでした。

B-Cus 1999/10/04(月) 17:05:43
$line はEUCにしたんでしょうが、$search もEUCにしましたか?
あと、スクリプト自体もEUCにしましたか?

スクリプトをEUCにするのは必須じゃないけど、もしSJISのまま安易に
 print "検索結果: @newlines";
などとすると、「検索結果」はSJIS、@newlines はEUCになります。

B-Cus 1999/10/04(月) 17:18:13
あ、失礼。スクリプトをEUCにしたって書いてあるじゃんね〜。

> これはどうしようもないのでしょうか?
どうしようもないことはないので、どこかにSJISが混じってるとか、
上記以外の場所で変な処理をしてるんでしょう。

まず、どの時点で化けているのか確かめてください。while ($line=<DB>)
で既に化けているとか、HTMLに書き出す時点で化けるとか。

あと、念のため最新の jcode.pl を使うとか。

ミント 1999/10/04(月) 20:39:50
ありがとうございます。
ちょっと説明不足でした。
検索結果が文字化けするのではなく、
入力文字が検索時に化けているようなのです。
上記の文字化け例は、
$searchとして出力して分かったものです。

つまり検索できていません。
当然、$totalは 0 になります。


print "Content-type: text/html\n\n";
print "<HTML><HEAD><TITLE>result</TITLE></HEAD>\n";
print "<BODY>\n";
$total = @newlines;
print "<br>$search--$total件見つかりました。<br>\n";
print "</BODY></HTML>\n";


ちなみにjcode.plはver2.10です。

B-Cus 1999/10/04(月) 21:26:46
じゃあ、$search が SJIS なんでは?
 &jcode::convert(*search,'euc')
などと明示的に EUC に変換してますか?

ミント 1999/10/04(月) 23:56:31
>&jcode::convert(*search,'euc')
>などと明示的に EUC に変換してますか?
入れていませんでした。

さっそく
&jcode::convert(*search,'euc');

$search =~ s/ / /g;$search =~ s/\t/ /g;
の前に入れてみましたが、結果はやはり同じです。
試しに、

@pairs = split(/&/,$buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
&jcode'convert(*value,'euc');
$FORM{$name} = $value;
}

の中にも入れてみましたが、当然ながらダメでした。

「東京」や「東京 文京区」だと文字化けして検索できないのに、
「東京 」だと(全角スペースを入れると)なぜかうまくいきます。

B-Cus 1999/10/05(火) 03:18:35
> &jcode'convert(*value,'euc');
これが最初から入ってたなら、既に EUC に変換してたってことですね。
他のところをチェックして下さい。繰り返しますが「EUC だからできない」
ということはありません。

あと、バイトコードで見てますか?
 $search =~ s/([^-_a-zA-Z0-9 ])/sprintf("%02lX ",unpack("C",$1))/eg;
などをバシバシ埋め込んで、$search/$line などが本当に EUC に
なっているか調べてください。

例えば「東京」は、EUC なら「c5 ec b5 fe」、SJIS なら「93 8c 8b 9e」です。

> ちなみにjcode.plはver2.10です。
最新版なので問題ないでしょう。

ミント 1999/10/07(木) 00:27:33
[[解決]]
>$search =~ s/([^-_a-zA-Z0-9 ])/sprintf("%02lX ",unpack>("C",$1))/eg;
>などをバシバシ埋め込んで、$search/$line などが本当に EUC に
>なっているか調べてください。

試したところ、EUCになっているようにので、
いろいろいじってみたところ、
いつの間にか正しく作動するようになってしまいました。
はっきりとした原因は分からないので、気持ち悪いのですが、
スクリプトの別の部分に誤りがあったようです。

丁寧に教えて下さいまして、ありがとうございました。

[上に] [前に] [次に]