• ベストアンサー

標準入力からのutf-8→euc-jpで一部文字化け

これまでeuc-jpで作られていたHTMLフォームページをutf-8に変更したところ、フォームメールCGIの文字列処理で「~」「-」「 」(半角スペース)など一部の文字が文字化けするようになってしまいました。 Jcode.pm → Encodeに変更してみても症状は変わりませんでした。 Encodeは初めて使うのですが、過去ログを見てもよく分かりません・・・ どうぞお力添えをお願いします。 (1)下記のperlの記述方法で間違っている箇所はありますか? (2)正しく出力できる方法がありましたら、教えてください。 (3)http://oshiete1.goo.ne.jp/kotaeru.php3?q=1540626 で話されている、右側の折れ曲がった「~」はどうやって入力するのでしょうか? (3)perl側もutf-8で記述すれば、文字化けなど発生せずに処理出来るものなのでしょうか? ↓perl5.8 文字コードeuc-jp #!/usr/bin/perl use Encode;#### if ($ENV{'CONTENT_TYPE'} =~ /application\/x-www-form-urlencoded/i) { binmode(STDIN); read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); @data_s = split(/&/,$buffer); foreach $buffer (@data_s) { ($key,$value) = split(/=/,$buffer); $value =~ tr/+/ /; $value =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C",hex($1))/eg; $value = encode("euc-jp", $value);#### print "$key = $value\n"; } }

  • qowop
  • お礼率100% (11/11)
  • Perl
  • 回答数2
  • ありがとう数2

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

  • ベストアンサー
回答No.2

まず、Encodeモジュールのencodeメソッドとdecodeメソッドは単純に文字コードの変換を行うものではありません。 詳細は参考URLを見てください。簡単に言うと、特定の文字コードの文字列とPerl内部のUTF-8コードとの相互変換をするためのメソッドです。 Encodeモジュールを使って文字コードの変換をするときは、from_toメソッドで、 Encode::from_to($value,"utf-8","euc-jp"); とするのが正しいです。 ------------------------------------------------ これを踏まえて。 「~」「-」「 」が正しく変換されない理由は、Encodeによるものではないと思われます。 上記文字はベンダ依存文字で、元のコードからUTF-8にどうマッピングするかは文字コードを変換するプログラムの実装次第です。 たとえば、Windowsのブラウザ(shift-jis)からUTF-8に変換し、そのUTF-8を別のシステムでEUC-JPに再度変換するとコードポイントが異なるため文字化けが発生する可能性があります。 Perlでも内部で扱う文字変数を入出力すべてUTF-8で扱うようにすれば文字化けは起こらなくなります。 が、それでも後で別の文字コードに変換しようとすると文字化けする可能性があります。(変換プログラム次第) どうしてもEUC-JPを使いたい場合、自ら変換表を書くのが一番確実かも?と思います。 決定的な解決策は示せませんが、ご参考までに。

参考URL:
http://www.pure.ne.jp/~learner/program/Perl_unicode.html
qowop
質問者

お礼

twinkleluz様、丁寧なご返答ありがとうございます。 色々と分からないことが多かったので、しばらく教えていただいたことについて調べてみたのですが、 http://lists.sourceforge.jp/mailman/archives/tcltkjp-develop/2002-November/000015.htmlを見て、ようやく理解しました。 EUC-JPに固執するより、UTF-8で処理するよう検討してみた方が良いのかもしれませんね。 有用な情報感謝いたします。 ありがとうございました。

その他の回答 (1)

回答No.1

Perl 5.8 で、プログラムそのものは euc-jp で書いてあって標準入力と標準出力を utf8 にしたいのであればこれを最初の方で指定するだけでいいと思いますよ。 use encoding 'euc-jp', STDIN => 'utf8', STDOUT => 'utf8'; use Encode; や encode(), decode() による変換は不要です。 注: 「~」などの変換についてはこれでいいかどうか分かりません。

qowop
質問者

お礼

noboru2000様、ご返答ありがとうございます。 ご指摘いただいた方法で試してみたのですが、全ての文字が「????」などと表示されてしまいました。 「use encoding」についてもう少し勉強してみます。

関連するQ&A

  • utf-8環境で標準入力からの全角文字にマッチさせる方法

    utf-8でフォーム処理のコードを書いてます。 euc-jpで動作していた全角文字の正規表現がutf-8で動作しません。 単純な「$str =~ /あ/」のような書き方ではなく、別な指定方法が必要なのでしょうか? ・perl5.8 文字コードutf-8 標準入力側文字コードutf-8 use utf8; my(%POST,$buffer,$key,$value,@data_s); if ($ENV{'REQUEST_METHOD'} eq 'POST') { if ($ENV{'CONTENT_TYPE'} =~ /application\/x-www-form-urlencoded/i) { binmode STDIN; read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); @data_s = split(/&/,$buffer); foreach $buffer (@data_s) { ($key,$value) = split(/=/,$buffer); $value =~ tr/+/ /; $value =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C",hex($1))/eg; if ( exists ($POST{$key}) ) { $POST{$key} .= '<>' . $value; } else { $POST{$key} = $value; } } } } binmode STDOUT,":encoding(utf8)"; print "Content-type: text/html; charset=utf-8\n\n"; print "<br>\n"; foreach $key (keys %POST) { if ($POST{$key} =~ /[0-9]/) { print "全角数字にマッチ<br>\n"; }###### print "$key = $POST{$key}<br>\n"; } exit;

    • ベストアンサー
    • Perl
  • 文字コードEUCのPerlプログラムが文字化けしてしまいます

    Perlで書かれたCGIを実行しようとしているのですが、プログラムはEUCで記述されているそうです。nkf -g ***とするとEUC-JPとなります。 print " <META http-equiv=\"Content-Type\" content=\"text/html; charset=EUC-JP\">\n"; とも記述されているのですが、ブラウザで実行(閲覧)すると文字化けして、ブラウザのエンコードは、Unicode(UTF-8)になっています。 ちなみに、OSはCentOS5.2です。 どうやったら、EUCで記述されたCGIが文字化けせずに実行できるのでしょうか? teratermでサーバに接続語、viコマンドで表示しても文字化けしています。ファイルの文字コードをEUCからUTF-8にして(nkf -w ***)、ブラウザでアクセスしても文字化けしてしまいます。

    • ベストアンサー
    • Perl
  • EUCのファイルを開くとUTF-8になる

    文字コードがEUCのperlで書かれたCGIをブラウザで表示すると、UTF-8となっています。(自動認識と設定していた場合) その場合は、文字化けしてしまいます。 ブラウザの文字コードをEUCに変更すると、文字化けせず表示されます。 perlプログラムは、EUCで書かれているのに、ブラウザでは(自動認識と設定していた場合)、UTF-8となる理由はどこにあるのでしょうか? perlプログラムでは、METAヘッダにEUC-JPと記述されています。 ちなみに、サーバのOSはCentOSです。(httpd.confでは、UTF-8が設定されています)

  • Sendmailの文字化けについて

    以前にも同じ質問をしたのですが、いまいち解決していないので、もう一度質問させて頂きます。 ホームページでsendmailをつかってフォームより記入してもらった内容を自分のところと確認メールとして記入した人のところに送るようにしていますが、確認メールが文字化けすることがあるようです。 しかし、全ての人に対して化けるというわけではなく、ほとんどの場合は大丈夫なようですが、一部の人に対してだけ化けるようです。 関係しそうな部分を大まかに書くと下記のようにしておりますが、間違っているでしょうか? if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/,$buffer); foreach $pair (@pairs){ ($name, $value) = split(/=/, $pair); $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; &jcode'convert(*value,'sjis'); &jcode'convert(*name,'sjis'); $xx =$value; &trans; $value = $xx; } sub trans{ $from='[@01-9A-Za-z._-]'; $to='[@01-9A-Za-z._-]'; &jcode'convert(*xx, 'euc'); &jcode'convert(*from, 'euc'); &jcode'convert(*to, 'euc'); &jcode'tr(*xx, $from, $to); &jcode'convert(*xx, 'sjis'); } &jcode'convert(*message,'jis'); if (!open(MAIL,"|$sendmail $mail_address")) {&error;} &jis("Subject: $mailname"); print MAIL "$msg\n"; print MAIL "To: $mail_address\n"; print MAIL "From: $mailfrom\n"; print MAIL "\n"; print MAIL "$message"; close(MAIL); sub jis { $msg = $_[0]; &jcode'convert(*msg, 'jis');}

    • ベストアンサー
    • Perl
  • PHPでUTF-8からEUC-JPにエンコディングしたときに、一部の文

    PHPでUTF-8からEUC-JPにエンコディングしたときに、一部の文字が文字化けしてしまいます。(1)という文字です。データベースをEUCで作っていて、すでに色々なデータが入っているので、データベースをUTF-8とするわけにもいかないでの、なんとかEUCで保存しようとしているのですが・・・。 "テスト(1)"(UTF-8)をmb_convert_encodingでEUCにして、保存しますと、"テスト?"となっています。 テスト(1)をUTF-8の状態でブラウザで確認しますと、文字化けしないできちんと「テスト(1)」と表示されます。やはり、Mysqlに保存するときに文字化けしています。どなたか、似たような経験のある方がおりその原因がお分かりでしたら、教えてください。SJISにあるようなダメ文字というものなのでしょうか。確か「まぐまぐ」というメルマガの編集でも(1)という文字は使えませんでした。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • euc-jp で文字化け

    euc-jp で文字化け euc-jp で打ち込むと、ブラウザ上では正常に映るのですが、ブラウザからソースを見ると 文字化けしてしまいますし、そういうサイトをよく見ます。これはSEO上影響は ないのでしょうか? ブラウザはIE7です。

    • ベストアンサー
    • HTML
  • UTF-8で文字化けしないようにするには?

    Shift-jisのページだったのですがリニューアルを機に文字コードを utf-8に変更してページを作っています。 メールフォーム用のcgiは以前と同じものを使いたいのですがページを utf-8で作ったために送信すると文字化けしてしまいます。 cgi自体をutf-8で保存しましたが同じ結果でした・・・ 確認ページがあるわけでもなく必須の項目が埋まっていれば送信するような シンプルなものなのですがutf-8で文字化けしないようにするには どのように変更したらいいのでしょうか? ソースは以下の通りです。 #!/usr/bin/perl require "jcode.pl"; require "mimew.pl"; $SENDMAIL = '/usr/sbin/sendmail'; $MAILTO = 'mail@example.com'; $MAILSUBJECT = 'メールフォームより'; $query = $ENV{'QUERY_STRING'}; foreach $pair (split(/&/, $query)) { ($key, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg; $form{$key} = $value; } $msg .= "----- 連絡先 -----\n"; ~~フォーム処理につき省略~~ if ($bad_input) { print <<END; Content-type: text/html <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>エラー</title> </head> <body> <center> <h1>エラー</h1> <div>必須項目が入力されていません。</div> </center> </body> </html> END }else { $mail_to = mimeencode($MAILTO); $mail_from = mimeencode($form{'mail'}); $mail_subject = mimeencode($MAILSUBJECT); $body = jcode::jis($msg); $head = <<END; To: $mail_to From: $mail_from Subject: $mail_subject Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-2022-JP END open (MAIL, "| $SENDMAIL -i -t -f $form{'mail'}") or die("Error: Can't open pipe for sendmail"); print MAIL $head, $body; close MAIL; print <<END; Content-type: text/html <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>送信完了</title> </head> <body> <center> <h1>送信完了</h1> <div>下記の内容で送信しました.</div> <textarea cols="48" rows="24"> $msg </textarea> </center> </body> </html> END }

    • 締切済み
    • CGI
  • "ー"を含むとサーバーエラーになる

    HTMLのShift_JISに合わせて、Jcode.plで日本語コード変換のeucをsjisに変更したのですが、"ー"が$FORM{'key'}に含むとサーバーエラーになります。 どうしたら、sjisで"ー"など一部文字でエラーなく処理できるのでしょうか? アドバイスお願い致します。 if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/,$buffer); foreach $pair (@pairs) { ($name,$value) = split(/=/, $pair); $name2 = $name; $value2 = $value; $FORM2{$name} = $value; $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; &jcode'convert(*value,'sjis'); #←ここを変更

    • ベストアンサー
    • CGI
  • Jcode.plを使用してコンバート

    if($ENV{\'QUERY_STRING\'} eq \"\"){ read(STDIN, $buffer, $ENV{\'CONTENT_LENGTH\'}); }else{ $buffer = $ENV{\'QUERY_STRING\'}; } @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,\'sjis\'); $form_data{$name} = $value; } Getメソッドで文字「?a=あ」をperlのJcode.plを使用してコンバートしましたが、 ブラウザのURL表示部は「?a=%82%A0」となり、shift_jisの16進数表示されてしまいます。 クッキーに取り込んで表示しても??と表示されてしまいます。 何かしら変換しているみたいのですが、 変換方法はあってるのでしょうか?

    • ベストアンサー
    • Perl
  • 「繝・せ繝・」となる文字化け

    「テスト」を以下でデコードすると「繝・せ繝・」となってしまいます。 URL test.cgi/q_テスト/ $ENV{'PATH_INFO'}と「q_テスト」を使うことを前提として、「テスト」と正常に取る方法はありますでしょうか。 ご教授お願いします。 $buffer = $ENV{'PATH_INFO'}; $buffer = substr($buffer,1); @lens = split(/\//,$buffer); foreach $len(@lens){ ($name, $value) = split(/_/,$len,2); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; &jcode'convert(*value,'sjis'); $value =~ s/\t/ /g; $value =~ s/\n//g; $FORM{$name} = $value; }

    • ベストアンサー
    • Perl