Perl utf8上でshiftjisをデコード

このQ&Aのポイント
  • Perlでutf8上でshiftjisをデコードする方法について教えてください。
  • URLエンコードされた文字をUTF8としてブラウザに表示させたいが、正しく表示されない問題が発生しています。
  • 環境はlinux apacheレンタルサーバで、Perlのバージョンは5.006001です。
回答を見る
  • ベストアンサー

Perl utf8上でshiftjisをデコード

以下の環境にてURLエンコード(shiftjis)された文字を、UTF8として ブラウザに表示させたいのですが、上手く表示されません。 環境: サーバ:linux apache レンタルサーバ ※Encode.pm、Jcode.pm無し。追加モジュールインストール不可。 Perl version: 5.006001 ソースエンコード:utf-8 実行ソース: ------------------------------------ use utf8; require 'jacode.pl'; # $mojiに予めURLエンコードされた文字が格納されています。 # 例として「マウス」デコード前(%83%7D%83E%83X)とします。 #URLデコード $moji =~ s/%(..)/pack("c",hex($1))/ge;  #デコードされたsjis文字をUTF8へコンバート jcode::convert(\$moji, "utf8","sjis"); print ($moji); ----------------------------------- 例のように「マウス」と言う文字が$mojiに格納されている場合、 以下のような文字化けとなってしまいます。 ツマ燿セツス 正常にマウスと表示させるにはどうすればよろしいのでしょうか。 アドバイスを宜しくお願いします。

  • Perl
  • 回答数8
  • ありがとう数15

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

  • ベストアンサー
  • taco0603
  • ベストアンサー率63% (21/33)
回答No.1

はじめまして。 自分はperl5.8から使い始めたものです。 >require 'jacode.pl'; ええと、jcode.plの質問ですよね? そもそもjcode.plはutf8に対応してません。 use utf8プラグマも確かperl5.8以上じゃないと動作しなかったような…。 まぁnkfやiconvなどのUnicodeに対応済みの文字コードを変換するコマンドがあれば、perlからシェル呼び出して上手く変換できるかもですが、ソースコードの作りが面倒くさいと思います。 perl5.8以上インストールするか、レンタルサーバー変えたほうがいいと思います。 Encode.pmがあれば悩む必要がありませんよ、まぁ無理なのかもしれないでしょうけど。

cinquecent
質問者

補足

早速アドバイス有難うございます。 jcodeではなくて、jacode.plというモジュールが出ているので、使ってみたのですが・・・。 http://fsasaki.sakura.ne.jp/WikiFan/wiki.cgi?Perl%A5%E9%A5%A4%A5%D6%A5%E9%A5%EA%2Fjacode.pl あまり、まだ一般的ではないのでしょうか?

その他の回答 (7)

  • taco0603
  • ベストアンサー率63% (21/33)
回答No.8

原因がUTF-8フラグであれば、文字化けも直りそうですね。 URLデコード前にUTF-8フラグが意図せず混入しているということで、予想ですがPerlモジュールかライブラリを使っていてその戻り値をpackしているんじゃないかなぁと。 XML::LibXMLなんかは戻り値をPerlの内部文字列で返してくれるので、ハマったことがあります。 頑張ってください。

cinquecent
質問者

お礼

色々試行錯誤しましたが、PerlでUTF8を制御するには5.8系以上を使わない駄目だという結論に至りました。 みなさま色々アドバイス頂きましてありがとうございました。 大変勉強になりました。 また、何かありましたら宜しくお願い致します。

cinquecent
質問者

補足

アドバイス有難うございました。 色々試行錯誤していますが、未だ解決できていません。 文字部分はとりあえず省略できるので、その他必要なステータスだけを拾い上げ、 文字をクッキーに保存して運用をしています。 現在調べようとしているのは、 ソースがeucベースにて渡される値を $moji = Encode::decode('shiftjis',$moji); $moji = Jcode->new($moji)->euc; とすると正常になるようなのですが、 当方の環境では使えないプラグマなので これに代わる機能は無いかと模索しています。 何か、アドバイスありましたらよろしくお願いします。

  • taco0603
  • ベストアンサー率63% (21/33)
回答No.7

どうやらDevel::Peekで出力結果をファイルに書き込みたいようですね。 参考URLの通り、PerlIO経由でSTDERRを開けば出来ますよ。 use Devel::Peek; my $stderr; close STDERR; open STDERR, ">", \$stderr or die $!; Dump $moji; print "stderr:{$stderr}\n";

参考URL:
http://www.donzoko.net/cgi-bin/tdiary/20060208.html
cinquecent
質問者

補足

ありがとうございました。 お陰様でDUMPをファイルに出力することが出来ました。 結果は以下の通りとなり、 どうやらURLデコードしてもUTF8フラグが立っている?ようでした。 【URLデコード前】 SV = PV(0x87359bc) at 0x853264c REFCNT = 1 FLAGS = (PADBUSY,PADMY,POK,pPOK,UTF8) PV = 0x86e5b40 "%83%7D%83E%83X"\0 CUR = 14 LEN = 15 【URLデコード後】 SV = PVMG(0x85dede0) at 0x853264c REFCNT = 1 FLAGS = (PADBUSY,PADMY,SMG,POK,pPOK,UTF8) IV = 0 NV = 0 PV = 0x872ef50 "\302\203}\302\203E\302\203X"\0 CUR = 9 LEN = 15 MAGIC = 0x8751120 MG_VIRTUAL = &PL_vtbl_mglob MG_TYPE = 'g' MG_LEN = -1 まだよくわかっていませんが、これからコードについて調べたいと思います。 何かアドバイスありましたらお願いします。 有難うございました。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.6

DUMPがうまいいかないのなら、適当なテキストファイルに出力して確認したらどうでしょう? open OUT ">> debug.txt" ; # 処理前 print OUT $moji ,"\n" ; # デコードして print OUT $moji ,"\n" ; # convertして print OUT $moji ,"\n\n" ; みたいに。 そのあと、そのままodでダンプするとか、PCにコピーしてバイナリエディタで読むとかして、それぞれがどんなコードになっているか調べるとよいでしょう。

cinquecent
質問者

補足

アドバイス有難うございます。 おっしゃるようにファイル出力は行っていたのですが、 何故こうなるのか分からず途方に暮れていました・・・。 ・ファイル出力結果 URLエンコード前:%83%7D%83E%83X URLエンコード後:ツマツウツス (←ツは半角カナ、エディタはSHIFT-JIS) shiftjisからutf8へコンバート:†쎿슃†促茠††⃃뿂茠⁏쎃側†쎿슃†促荛(エディタはUTF8) 試しに$moji="%83%7D%83E%83X";としてテキストを代入して行うと 「マウス」と正常に出力されます。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.5

#4の方法で use lib qw(./lib); use Jcode; moji="%83%7D%83E%83X" ; $moji =~ s/%(..)/pack("c",hex($1))/ge; # Jcode::convert(\$moji, "utf8","sjis"); print $moji,"\n"; 単純にこれだけのスクリプトを動かしたらどうなります? 手許に5.6は無いので完全な再現にはなりませんが、Shift_JISでマウスと出力されました。 コメントを外せばUTF-8になりました。 $mojiに入っているURLエンコードが間違っているとか、実は元がShift_JISでは無いとか、そんなことは無いでしょうか? あとは、画面表示だけの問題とかはないでしょうか?

cinquecent
質問者

お礼

補足です・・・。 私のソースに強制的にURLエンコード値(%83%7D%83E%83X)代入して 処理しましたら、正常に表示されました。 実際のURLエンコード値がどうやら「表示」と「保持」している値が違うようです・・・・。 何故こうなるのかが理解できません。 なにかアドバイスありましたら、よろしくお願いいたします。

cinquecent
質問者

補足

引き続きアドバイス有難うございます。 ご教授頂いた方法でしたら、おっしゃる通り正常に表示されました。 ・・・私のソース上で実行したURLエンコード文字列自体、 表示した限りでは同じ文字なのですが、 (表示した文字列をここに張り付けてました) その直後にURLエンコードするとおかしくなっているようです。 URLエンコード文字列に何かフラグが立ってしまっているのでしょうか? これをDUMPで調べようとしているのですが、それがうまくいかず苦戦してます。 表示としましては、ブラウザのエンコードを色々変更したり、CharSetを指定して行っているので、 恐らく大丈夫だと思いますが・・・。

  • ariman_
  • ベストアンサー率45% (27/59)
回答No.4

Jcode.pmのバージョン0.88をダウンロードして、 http://search.cpan.org/~dankogai/Jcode-0.88/ 解凍して、Jcode.pm、Jcodeディレクトリをlibディレクトリを作成して、その中に入れます。 それを、実行ファイルと同じ場所に設置し、 (それだけでは駄目な場合は、Unicodeディレクトリもlibディレクトリ内に設置) 実行ファイルは、初めに書かれた記述の use utf8; require 'jacode.pl'; を use lib qw(./lib); use Jcode; に変更し、jcode::convertは、Jcode::convertとJcodeで変換する記述に変更してみては如何ですか?

cinquecent
質問者

補足

アドバイス有難うございます。 ご指示通り、libディレクトリにJCODEソースを設置し、ソースを書き直して 実行してみました所、文字化けは以下のように変化しました。 †쎿슃†促茠††⃃뿂茠⁏쎃側†쎿슃†促荛 Unicodeディレクトリも同様に設置してみましたが同じでした・・・・。 補足としまして。 文字をURLデコードのみで、shift-jisをそのまま表示してみると ツマツウツス (←ツは半角になります) となっていました。 元の文字に何かフラグ?が立ってしまっているのでしょうか? 元の文字がおかしいとどうしようも有りませんよね。 URLデコードがおかしいのでしょうか。

  • taco0603
  • ベストアンサー率63% (21/33)
回答No.3

No.1です。 jacode.plというライブラリあったんですね、勉強不足ですみません。 Perl5.8しか使ったこと無いんで、ごめんなさい。 で、ご提示のコードには特におかしいところは無さそうですが、まだ未解決なら、Devel::Peekで文字列をダンプしてスクリプトのどこの行で文字化けしてるか確認すべきかと。 何となくutf8プラグマが悪さしてる気がします。 頑張ってください。

cinquecent
質問者

お礼

いえいえ。アドバイス有難うございました。 XXXX.plはライブラリと呼ぶのですね。 勉強になりました。 Devel::Peekで問題個所を辿って、色々もがいてみます。 有難うございました。

cinquecent
質問者

補足

一つご教授ください。 Devel::Peekを使って解析しようとしているのですが、 これ自体がうまく出力されません。 アドバイス頂けませんでしょうか? ---------------------------------------------------------- # hogeをダンプしてdump.txtに出力させる。 use Devel::Peek; open(OUT, "> ./dump.txt"); # ファイルを開く $old = select(OUT); # 標準の出力先を OUT に変更 print Dump($hoge); select($old); # 標準の出力先を元に戻す close(OUT); ---------------------------------------------------------- 何か出てくれたら解決の糸口にもなるのですが、 何も出力されません。 出力先をSTDOUTに戻しても同様です。 何か間違っているのでしょうか・・・。

  • sample_
  • ベストアンサー率76% (20/26)
回答No.2

私もtaco0603さんの意見と一緒で、perlbrew等で別のPerlをインストールできるのであればインストールして できないのであれば、別のレンタルサーバに移った方がよいのではないかと思います。 そもそもPerl5.6.1って2001年4月リリースのものですから11年前のツールを使っていることになりますし… それでも、どうしてもそのレンタルサーバしか選択しがなく、 それでもこのバージョンじゃないといけない縛りがあるのでしたら… 参考になるかもしれないページが見つかったのでパスをはっておきますね。 http://www.hidekik.com/cookbook/p2h.cgi?id=utf8p56

cinquecent
質問者

お礼

早速アドバイス有難うございます。 環境自体は事情で変更する事ができません・・・。 なんとかjcodeと同じものをと探しているとjacodeがあったから使ってみたのですが、上手くいきません・・・。 私の使い方が悪いと思いたいのですが。 リンクは参考になりました。 これでもう少し勉強してみます。

関連するQ&A

  • UTF-8から1文字ずつ変換するには?

    アクセスログのリンク元に含まれる検索キーワードがUTF-8の場合に、SJISに変換できないことがあります。 アクセスログはURLエンコードされたまま記録して、表示するときにデコードしてからJcode.pmでSJISに変換しています。時々変な文字になることがあるので、ログファイルのURLエンコードされた文字を取り出して順番を入れ替えてデコード、変換するとうまくいきます。 たとえば、 %E3%81%8D%E3%81%AE%E3%81%93%E7%8B%A9 は「きのこ狩」ですがうまく変換できません。これを %E3%81%AE%E3%81%8D%E7%8B%A9%E3%81%93と並べ替えると「のき狩こ」と変換されます。(1234を2143に並べ替え)へんてこだけど意味は分かるようになります。 文字の組合せによっておかしなことになるようなので、1文字ずつ(3バイト?)変換すれば確実だと思うのですが、やり方がわかりません。 ということで、そもそもこういう方法しかないのか、もしそうならどうやればいいのか教えてください。 URLエンコードされた部分だけ取り出せれば、%でsplitして再度%を付けてから9文字(3バイト分?)ずつ変換すればいいのかなと思うのですが…。

  • perl cgi のエンコード SHIFT->UTF-8

    こんにちは初心者です。 現在、既存のperl cgiをカスタマイズしております。 エンコードをshift_jisからUTF8に変更したいのですが、表示はCGI自体をUTF-8に変更し普通に見ることができるのですが、書き込みをしようとすると文字化けがおこります。 jcode.plをjcode.pmに変換すればよいらしいまでは分かったのですが、どこをどう変換すればいいのかjcode.pmのサイトを見ても理解できません。簡単な説明サイト紹介やアドバイス等をいただけませんでしょうか?

    • 締切済み
    • CGI
  • デコードに困っています。

    エンコードされた文字をrawurldecodeでデコードしたいのですが、Shift_JISやEUC、UTF-8によってデコードされる形が異なります。 METAでShift_JISを指定してればShift_JISでエンコードされた値もデコードすればしっかりと表示されます。しかしUTF-8など異なるタイプではMETAがShift_JISなのでしっかりと表示されません。どうすればすべてのタイプに対応させることが可能なのでしょうか?

    • 締切済み
    • PHP
  • UTF8 URLエンコード

    こんにちわ。 PerlのCGIです。 今までEUCとsjisの変換連打で開発を乗り切って来たのですが、 さすがに古すぎて周りの人が迷惑らしいので、初めてUTF8を使うことになりました。 一応全部UTF8だけで作ろうと思います。 大まかな質問は三つです。 1:   UTF8は可変ビット (バイト単位ではない) の、   ほぼ全ての国際言語対応文字コードと言う認識で合ってますか? 2:   そうなってくると、データの送受信などのURLエンコードは不要ですか?必要ですか? 3:   もしURLエンコードが必要なら、一般に通用する変換方法を教えてください。   ついでなんでデコードの記述もお願いします。 すみませんがよろしくお願いします。

    • 締切済み
    • CGI
  • URLデコードをしてくれるリネームソフトを探しています

    URLデコードをしてくれるリネームソフトを探しています URLエンコードされた名前のファイル名があるのですが、これを日本語のファイルに直したいです ファイル数が結構あり、手で直すのはちょっと無理があるのでURLデコードをしてくれるリネームソフトを探しています 文字コードはUTF-8です よろしくお願いします

  • Perl+UTF8で文字化け

    以下の環境にてメール送信プログラムを作成していますが、 ありがちな文字化け、且、ボディーが表示されない不具合が発生しています。 サーバ:linux apache レンタルサーバ ※Encode.pm、Jcode.pm無し。モジュールインストール不可。 Perl version: 5.006001 ソースエンコード:utf-8 自分の解釈としてはutf8で記述しているので、 charset=utf-8にしておけば、 MIMEエンコードさえしてやれば 表示できると考えているのですが、 やはり甘い考えなのでしょうか? また、同サイト質問NO2868794も参考にさせていただきましたが、上手くいきません。 以下ソース(エンコード:utf-8) use utf8; use MIME::Base64; use POSIX; ※アドレス表記はこのサイトの投稿チェックに引っかかるので省略します。 my $to = 'XXXX@XXXX'.XXX; my $from_nm = "送信者名"; my $from_adr = "XXXXX@XXX.XXX"; my $subject = "メール表題"; my $body = "本文"; # 送信者名を MIME エンコード encode_base64($from_nm,""); # subjectを MIME エンコード encode_base64($subject,""); $subject = "=?utf-8?B?" . $subject . "?="; # 本文を MIME エンコード encode_base64($body); my $MailPass = "XXXX/XXXX/XXX"; #SendMail Pass open(MAIL,"| $MailPass -t"); #======================================================== print MAIL <<"EOF_MAIL"; From: $from_nm<$from_adr> To: $to Subject: $subject Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: base64 MIME-Version: 1.0 $body EOF_MAIL #======================================================== close MAIL; その他、色々ググっては見たのですが、自分ではみつけられず、 どうかアドバイスありましたらよろしくお願いいたします。

  • shift-jisからutf8に変換

    解決に至らなかったので再度お尋ねします。 CGIのコードを見てくださいますか。 http://hotpegasus.bov.jp/mail.txt (必要な部分だけ表示しておりますので、そのままアップしても機能はしません) 改修した箇所は以下のです。 <meta http-equiv="Content-Type" content="text/html;charset=shift_jis"> &jcode'h2z_sjis(*contenido) &jcode'convert(*subject,'sjis'); &jcode'convert(*infor,'sjis'); &jcode'convert(*contenido,'jis'); &jcode'convert(*res_msg,'jis'); print "Content-type: text/html;charset=shift_jis\n\n"; ↓ sjis関連をutf8に書き換え、jcodeの頭文字をJに書き換え <meta http-equiv="Content-Type" content="text/html;charset=utf8"> &Jcode'h2z_utf8(*contenido) &Jcode'convert(*subject,'utf8'); &Jcode'convert(*infor,'utf8'); &Jcode'convert(*contenido,'utf8'); &Jcode'convert(*res_msg,'utf8'); print "Content-type: text/html;charset=shift_utf8\n\n"; require 'jcode.pl'をuse Jcode;に書き換え ※jcode::" となっている箇所はありません 結果 メールフォームはエラーや文字化けは出なくて成功しましたが、メール受信の際、ThunderbirdPortableメーラーでは全て文字化け(文字エンコーディングは「日本語ISO-2022jp」となっています)、ウェブメールのgmailでは内容は文字化けになっていませんが、タイトルが文字化けになっています。 どこが悪かったのでしょうか? 宜しくお願いします。

    • 締切済み
    • CGI
  • 文字コードsjisをUTF8に書き換えたい

    CGIの勉強中の者です。 文字コードはSJISで保存しているCGIをUTF8コードに換えるには何が必要でしょうか? HTMLならmeta内をSJISからUTF8に変更し、TeraPadなどのテキストエディタでUTF8に保存すればオッケーなんですが。 CGIの場合はHTMLと違って、換えるには複雑なのでしょうか? CGIプログラムの中では以下の「sjis」を「UTF8」に書き換えし、UTF8で保存しましたけど、文字化けが出てます。 <meta http-equiv="Content-Type" content="text/html;charset=shift_jis"> &jcode'h2z_sjis(*contenido) &jcode'convert(*subject,'sjis'); &jcode'convert(*infor,'sjis'); &jcode'convert(*contenido,'jis'); &jcode'convert(*res_msg,'jis'); print "Content-type: text/html;charset=shift_jis\n\n"; 宜しくお願いします。

    • 締切済み
    • CGI
  • base64_decodeに関して

    base64でエンコードされたPHPソースをデコードし、 その内容を表示させるスクリプト(base64.php)を 実行すると、ブラウザには decode.txt の様に 文字化けした内容が表示されます。 元のソースを表示させる方法は無いでしょうか? base64.php、decode.txt は以下よりダウンロードし、 検討して下さい。 ================================================================ http://www.hp-toolbox.com/base64_decode.zip ================================================================ 宜しくお願い致します。

    • ベストアンサー
    • PHP
  • phpmyadmin文字化けについて

    user_id user_name   mail comment create_datetime    del_flag 4 てst てst 2011-02-13 06:12:50    0 5 あああッ て    2011-02-13 06:15:14     0 このような感じで文字化けします [mysqld] character-set-server = utf8 collation-server = utf8_general_ci init-connect = SET NAMES utf8 default-character-set = utf8 [mysqldump] default-character-set = utf8 [mysql] default-character-set = utf8 の設定もしました 照合順序をtf8_unicode_ciにしました 色々ググッたのですがこのくらいしか設定するものがでてきませんでした ブラウザはchromで見ていますブラウザ側もutf-8になっています 他にもfirefox IEでも同じ結果でした 他に設定するべき項目があったらよろしくお願いします

専門家に質問してみよう