• 締切済み

UTF-8へのエスケープ方法

ホームページに検索窓をつけてYahoo辞書を検索するようなCGIを作ったのですが、検索すると、例えば、「辞書」と入れると、キーワードが%8E%AB%8F%91と、Shift-JISでエスケープされているようなんです。 これを%e8%be%9e%e6%9b%b8と、UTF-8でエスケープするようにするのはどうすればいいんでしょうか。 こんなソースです。 初心者なのでよろしくお願いします。 #!/usr/local/bin/perl #use strict; my %engine = ( google => 'http://www.google.com/search?ie=Shift_JIS&safe=off&q=', yahoo => 'http://search.yahoo.co.jp/search?ei=SJIS&p=', kokugo => 'http://dic.yahoo.co.jp/dsearch?enc=UTF-8&stype=0&dtype=0&p=', eigo => 'http://eow.alc.co.jp/', ); my (%in); %in = map { split(/=/, $_, 2) } split(/[&;]/, $ENV{QUERY_STRING}); search($in{word}, $in{engine}); exit; sub search { my ($word, $search) = @_; # 謎の検索エンジンだったら google $search = $engine{$search} || $engine{google}; # アルクは検索語をエスケープしない if($search eq "http://eow.alc.co.jp/"){ $word =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg; print qq(Location: $search$word/UTF-8/\n\n); }else{ print qq(Location: $search$word\n\n); } }

みんなの回答

  • okmotokun
  • ベストアンサー率59% (92/155)
回答No.6

No.4です。 >漢字ならうまく表示されるようになったのですが >「あ」なんかはうまく表示されません。 >あ → 縺・ になります 勘違いではありませんか。 「あ」(\xE3\x81\x82) は、Shift_JISモードのエディタやブラウザで見ると「縺・」のように見えます。 ↓「UTF-8 日本語文字一覧」 http://webmastertool.jp/other/utf.html

mayumi9999
質問者

お礼

お返事ありがとうございます。 $word = Jcode->new( $word, "sjis")->utf8; の後に $word =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg; をくわえると 「あ」が%E3%81%82の表示になりました。 いろんな書き方があって難しいですね・・・ ありがとうございました。

すると、全ての回答が全文表示されます。
  • zxcv0000
  • ベストアンサー率56% (111/196)
回答No.5

No.1 & No.3 です。 ご自身のページは UTF-8 がお勧めですが、SJIS にしたいなら、閲覧者のブラウザ設定によらず入力がSJISで送られる事の確認はされた方が良いと思いますよ。 次に、アクセス先によって求めるコードが違うならCGIでコード変換せにゃならんのは致し方無いですね。 コード変換のポイントはふたつです。 1 %xx 形式のエンコードをそのコードの生形式にデコードしたりその逆の処理が必要になります。 これは、 use CGI; しておいて、 CGI::unescape() と CGI::escape() で良いと思います。 2 入力のデコード(unespape) が済んだ次に入力のコードを求められるコードに変換する処理が必要です。 これには選択肢と落とし穴が沢山あります。 日本語コード変換方法の主流が Jcode から Encode に替る過渡期だからです。 UTF-8以外の日本語コードが早く無くなればコード変換自体が不要になるんですけどね。 今後もPerlを使用されるなら Encode をお勧めします。 そうで無いなら、Jcode の方が判り易いかも知れません。 ただし、いずれの場合も入力コードの自動判定はやめましょう。 検索語の様な短い文字列を自動判定させても、結果は全く信頼できません。

すると、全ての回答が全文表示されます。
  • okmotokun
  • ベストアンサー率59% (92/155)
回答No.4

これでどうですか。 use Jcode; $str='エスケープする文字列'; for('sjis','euc','jis','utf8'){ ${$_}=$str; if(Jcode::getcode(${$_}) ne $_){ ${$_}=Jcode::convert(\${$_},$_); } ${$_}=~s/([^0-9A-F\/?=&])/sprintf("%%%02X",ord($1))/ieg; print "<b>[$_]</b><br>${$_}<br><br>\n" }

mayumi9999
質問者

お礼

返事が遅くなってすみません いろいろ悩んでたので・・・ こちらのようにしてみたところ 漢字ならうまく表示されるようになったのですが 「あ」なんかはうまく表示されません。 あ → 縺・ になります あ → %E3%81%82 にならないでしょうか $word =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg; が間違ってるのでしょうか? #!/usr/local/bin/perl use Jcode; my %engine = ( google => 'http://www.google.com/search?ie=Shift_JIS&safe=off&q=', kokugo => 'http://dic.yahoo.co.jp/dsearch?enc=UTF-8&stype=0&dtype=0&p=', ); my (%in); %in = map { split(/=/, $_, 2) } split(/[&;]/, $ENV{QUERY_STRING}); search($in{word}, $in{engine}); exit; #************************************************* sub search { my ($word, $search) = @_; $search = $engine{$search} || $engine{google}; $word =~ tr/+/ /; $word =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg; if($search eq "http://dic.yahoo.co.jp/dsearch?enc=UTF-8&stype=0&dtype=0&p="){ $word = Jcode->new( $word, "sjis")->utf8; }else{ } print qq(Location: $search$word\n\n); }

すると、全ての回答が全文表示されます。
  • zxcv0000
  • ベストアンサー率56% (111/196)
回答No.3

No.1 です。 この問題のポイントは、なぜSJISが渡されるのか、それは常にそうなのかだと思います。 CGIに SJIS⇒UTF-8 変換を入れても、SJIS以外で渡されるケースがあるならまずいですよね? だから、まず渡されるコードを固定する事を考えた上で、そのコードが用途に対して不適切なら変換するのが良いでしょう。 繰り返しますが、CGI内でのコード変換より渡されるコードを制御する事を先に考えるべきです。 以上、No.1 の回答の背景でした。

mayumi9999
質問者

お礼

ご回答ありがとうございます! UTF-8でホームページを作り直してみました。 すると、yahoo辞書はUTF-8で作成されているからか うまく表示されたのですが、 フレッシュアイは、ちゃんと表示されなくなりました。 (euc-jpだから??) できればCGIでshift_jisからUTF-8に変換したいのですが、 無理でしょうか・・・

すると、全ての回答が全文表示されます。
  • jjon-com
  • ベストアンサー率61% (1599/2592)
回答No.2
すると、全ての回答が全文表示されます。
  • zxcv0000
  • ベストアンサー率56% (111/196)
回答No.1

Webブラウザの仕様の範疇だと思いますが、送信したフォームを含むページが Shift_Jis なんじゃ無いでしょうか? UTF-8 にしてみては? CGIでは無くWebブラウザの挙動に注目して考えると、送信ボタンが押されて送信すべきデータ中に全角文字がある時、現在表示中の文字コードが使用されるのは自然な事だと思います。 IE6 には UTF-8 を強制するオプションもありますが、CGI作成者の立場としてはそれを前提にしちゃまずい場合が多いです。

すると、全ての回答が全文表示されます。

関連するQ&A