Perlの日本語文字コードはどうすべき?

このQ&Aのポイント
  • Perlでの日本語文字コードについてそれぞれのモジュールや関数の使い方について調べたが、混在して使用する際に問題が生じることがあった。
  • Jcode.pmやuse Encode qw(from_to encode)はjcode.plに代わる日本語変換のパッケージであるが、使用する際に注意が必要である。
  • また、メール送信での文字変換にEncode::from_to()を使用するが、その際にはuse Encode qw(from_to encode)が必要である。
回答を見る
  • ベストアンサー

perlの日本語文字コードはどうすべき?

perlで細かいことを理解できないままに呪文のように頭に require 'cgi-lib.pl'; require 'jcode.pl'; を使っていました。 そのうち文字化けなどの問題も出て、いろいろ調べたり質問したりして、jcode.plは古いからJcode.pmを使いなさいと指摘を受けたので、 require 'cgi-lib.pl'; require 'Jcode.pm'; と呪文変更を行いましたが、これについての使い方を理解せぬうちに、use Encode qw(from_to encode);としなさいと指摘を受け、 require 'cgi-lib.pl'; use Encode qw(from_to encode); と変えて使っていました。 ところが、このパターンを使っていたところ、GETでのデータの受渡がうまくできない(internal server error)となることに気づきました。 2つ目のパターンでも同じでした local($key,$val); undef(%in); &ReadParse; my($method) = $ENV{'REQUEST_METHOD'}; if ($method eq "GET"){ $QUERY_DATA = $ENV{'QUERY_STRING'}; }elsif ($method eq 'POST'){ read(STDIN, $QUERY_DATA, $ENV{'CONTENT_LENGTH'}); }else{ &error; } データの受信はこのようにはじめています。 そもそもJcode.pmやuse Encode qw(from_to encode);というのはjcode.plに変わる日本語変換のパッケージなのでしょうか? また、 require 'cgi-lib.pl'; require 'jcode.pl'; use Encode qw(from_to encode); とするとGETでの受渡も問題なかったのですが、2つを混在させても問題ないのでしょうか? というのも、メール送信で文字変換させるときに sub jis{ my $msg = $_[0]; Encode::from_to($msg, "shiftjis", "iso-2022-jp"); return $msg; } としているので、use Encode qw(from_to encode);がないとEncode::from_to()が使えないのかなと想像し2つをセットで使用しています。(冒頭でuse Encode qw(from_to encode)を宣言し、変換部分でEncode::from_to()を使用) jcode.pl、Jcode.pm、use Encode qw(from_to encode)、Encode::from_to()の関係について教えてください。 もちろん自分でもネットで調べてみましたが、思うように解説してあるところが見つからず困っています。

  • choei
  • お礼率63% (286/451)
  • Perl
  • 回答数1
  • ありがとう数1

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

  • ベストアンサー
  • root139
  • ベストアンサー率60% (488/809)
回答No.1

まず、よく使われる日本語関係のライブラリですが、下記の様になります。 ---------------------------------------- ■ jcode.pl http://mikeneko.creator.club.ne.jp/~lab/kcode/jcode.html 対応Ver.    : Perl4以降 対応文字コード : JIS(ISO-2022-JP), EUC-JP, シフトJIS 歌代和正さんによる日本語コード変換ライブラリ。 ■ Jcode.pm http://openlab.jp/Jcode/index-j.html 対応Ver.    : Perl5以降 対応文字コード : JIS(ISO-2022-JP), EUC-JP, シフトJIS, UTF-8, UCS-2 小飼弾さんによる日本語コード変換ライブラリ。jcode.pl の後継を意図? ■ Encode.pm http://search.cpan.org/dist/Encode/Encode.pm 対応Ver.    : Perl5.8以降 対応文字コード : JIS(ISO-2022-JP), EUC-JP, シフトJIS, UTF-8, UTF-16, etc... Jcode.pm と同じく小飼弾さんによる文字コード変換ライブラリ。Perlの標準ライブラリに含まれる。Jcode.pm の後継。 ---------------------------------------- > とするとGETでの受渡も問題なかったのですが、2つを混在させても問題ないのでしょうか? おそらく、jcode.plに含まれる関数を使っている箇所が残っていて、たまたま GET リクエストがあった際にそこを通ったのではないかと。 混在させることでエラーが発生したり誤動作することは無いと思われますが、混乱の元ですので jcode.pl の関数を使っている部分を書き換えた方が良いでしょう。 下記の行をスクリプトの中に入れれば、Internal server error の内容がブラウザに表示されるとおもいます。 use CGI::Carp qw(fatalsToBrowser); ※ エラーの情報がダダ漏れになりますので、外部に公開されていないサーバなどで試して下さい。また、修正し終わったらこの行は取り除いてください。 Perl 5.8 以降は、内部表現がUTF-8になるなど文字列全般の扱いが大きく変わったので、仕様をよく確認しておいた方が良いです。下記のサイトなどに詳しく説明されています。 http://hikoboshi.org/perl/utf8.html http://www.rwds.net/kuroita/program/Perl_unicode.html http://hikoboshi.org/perl/doc/encode_old.html Perl 5.8 以降では、入力された文字列は一度内部表現(UTF-8)に直して必要な処理を行い、出力する際にエンコードし直すのがセオリーようです。

choei
質問者

お礼

ありがとうございます。 教えて頂いた3つのサイトは読んだことありますが、全くの無知状態でフリーのコードを睨めっこしてperlを少しずつ使えるようになった経緯から、プログラムの基本が全く分かってなくって、なかなか説明を理解することができておりません。 (特に冒頭部分などは呪文のように一塊の処理を頭ごなしに記憶している状態です) use CGI::Carp qw(fatalsToBrowser); 教えて頂いたこのコードでエラーヶ所を探してみたところ、データを受けた後分解する際にforeachの中で &jcode'convert(*name,'sjis'); &jcode'convert(*value,'sjis'); がjcode.plの構文だったようで、ここで引っかかっていました。 そこをコメントアウトし、 #!/usr/bin/perl require 'cgi-lib.pl'; use Encode qw(from_to encode); local($key,$val); undef(%in); &ReadParse; my($method) = $ENV{'REQUEST_METHOD'}; if ($method eq "GET"){ $QUERY_DATA = $ENV{'QUERY_STRING'}; }elsif ($method eq 'POST'){ read(STDIN, $QUERY_DATA, $ENV{'CONTENT_LENGTH'}); } @pairs = split(/&/,$QUERY_DATA); foreach $pair(@pairs) { ($name,$value) = split(/=/,$pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; $name =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; #&jcode'convert(*name,'sjis'); #&jcode'convert(*value,'sjis'); $in{$name} = $value; } としてみたところ、とりあえずPOSTでもGETでもエラーなくshift-jisのファイルを読み込んでshift-jis形式でhtml出力をしてくれていますが、やはりこれはあくまでも入力時も出力時も変換されずに読み出し書き出ししているということになるのですよね? このperl(cgi)ファイルもwindows上のテキストアプリで作ってますので、shift-jis形式だとは思うのですが・・・おっしゃっておられるセオリーに合わせるならperlファイルもUTF-8で記述できるテキストアプリケーションを使って、入力時、出力時ともに変換すべきなのでしょうか。 とすると、どこでどのようにUTF-8にエンコードしてやればいいのでしょうか? すごく初歩中の初歩のことを聞いて恐縮ですが、ネットでPOSTやGETデータを受信して内部処理として使えるようにする記述例を探しても、まとまって記述されている物はどれもjcode.plを使っているものばかりで、Encodeで記述の最初(#!usr/bin/perl)からデータのデコードまでを記述されたサイトが見つからず、流れとしてどうやって記述していいのか分かりません。 jcode.plやJcode.pmを使わず、現在の王道(基本)的な最初の記述のくだりを説明したサイトでもご存じでしたらぜひ教えてください。 よろしくお願いします。

choei
質問者

補足

何度もすみません &jcode'convert(*name,'sjis'); &jcode'convert(*value,'sjis'); が、jcode.plでの文字変換でエラーだと気づいたと書きましたが、Encodeの場合だと Encode::from_to($name, "shiftjis", "cp932"); Encode::from_to($value, "shiftjis", "cp932"); でいいのでしょうか? 基本的に現在、shift-jisのファイルをshift-jis形式で作ったperlファイルで操作し、shift-jis形式のhtmlで出力しているので、ちゃんと変換されているのか検証することができず困っております。

関連するQ&A

  • jisコードで16進数の『3c』から始まる文字

    だけが文字化けしてしまいます。今までそういった現象はまったく起きていなかったのですが、突然発生するようになりました。 文字化けの内容。 『治』が『。』『爾』が『「』 といった感じで、jisコードの3c20の+3から3c60の+2までの文字が半角カタカナに化けてしまいます。 コード内容は以下です。 #!/usr/bin/perl #use KCatch qw( execdata );__DATA__ use CGI qw(:standard); use Encode; #use strict; #use warnings; require './jcode.pl'; require './mimew.pl'; ############################################# #処理開始 $query = CGI->new; if(param('handleName')){ $handleName = $query->param('handleName'); } if(param('nameLast')){ $nameLast = $query->param('nameLast'); # &jcode::convert(*nameLast,'euc-jp'); } if(param('nameFirst')){ $nameFirst = $query->param('nameFirst'); &jcode::convert(*nameFirst,'euc-jp'); } ################################ #送信メール成型 $Mail_A= <<"EOF"; $handleName $nameLast $nameFirst EOF ########################################## #コード変換 $Subject_A = &mimeencode($Subject_A); $Subject_B = &mimeencode($Subject_B); &jcode::convert(\$Mail_A,'jis'); &jcode::convert(\$Mail_B,'jis'); #受付側用を送信 open (SENDMAIL,"| $Sendmail -t -i"); print SENDMAIL <<"EOF"; To: $ToMailadd From: $mailAddress Subject: $Subject_A MIME-Version: 1.0 Content-Type: text/plain\; charset="ISO-2022-JP\" Content-Transfer-Encoding: 7bit $Mail_A EOF close SENDMAIL; です。足りない部分等ありましたら教えてください。

    • ベストアンサー
    • Perl
  • Perlの文字コード変換について

    ActivePerl-5.14を使っているのですが、文字コードの変換はどのようにすればいいのでしょうか。 ローカル環境で動かしているのですが、Shift-JISのテキストを読み込んで、EUC-JPに変換したいと思っているのですが、 今まで5.8を使っていたので、Jcodeを使って、&Jcode::convert(\$txt,'euc'); としていたのですが、5.14ですと use Jcode;  の時点でエラーになってしまいます。 use Encode; を使って、 from_to($txt, 'shiftjis', 'euc'); としてみましたが、 from_to($txt, 'shiftjis', 'euc'); のところでエラーになってしまいます。 ActivePerl-5.14ですと、どのように文字コードの変換をすればいいのでしょうか。 どなたか教えてください。 よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • Encode.pmで文字コードの判別

    文字コードの変換に以前はjcode.plを利用していたのですが、Perl5.8をインストールしたのでEncode.pmでこれを行おうと思っています。 変換にはfrom_toを利用しようと思っているのですが、肝心の文字コードの判別方法が分かりません。 jcode.plでいうところのgetcodeに当たる機能は、用意されているのでしょうか? ご存知の方おられましたら、よろしくお願いします。

    • ベストアンサー
    • Perl
  • Perlでuse strictと %inの共存

    use strictを使うと、変数の使用に厳密にチェックしてくれるので、便利だと思い使いましたが、ReadParse後の%inを利用する場合に宣言されていないエラーが表示されます。意味的には正しいですが、$in{'test'}など CGIで受け取った内容が扱えなくなるので、困っております。何か解決方法は有るのでしょうか? use strict; require 'cgi-lib.pl'; require 'jcode.pl'; &ReadParse; my $x = $in{'md'};

    • ベストアンサー
    • Perl
  • PerlのCGIでフォームのテキスト配列をPerlで取得するには?

    フォームで通常は同じ名前のデータを取得することは無いのですが 表計算のように同じ名前の場合、データの取り出し方がわかりません。 以下、通常の1件の場合のソースです。 #!/usr/bin/perl $| = 1; use strict; our %in; use CGI::Carp qw(fatalsToBrowser); use CGI qw(:standard); require 'jcode.pl'; require 'cgi-lib.pl'; # #-----分岐----- &ReadParse; # 配列でない場合 my $namae = $in{'namae'} print "$namaeで名前が1件表示される"; # これをフォームで namaeが配列になった場合、 #<input type="text" name ="namae"> #<input type="text" name ="namae"> #<input type="text" name ="namae"> # のような場合、3件取得する場合 exit; __END__

    • ベストアンサー
    • CGI
  • perl5.8.6日本語の置換について

    教えてください。perl5.8.6の日本語処理で行き詰まっています。 下記のプログラムをeuc-jpで書いて動作させたところ、s///gの 置換がうまくいきません。 何か間違っているのでしょうか。 weather.pl --------------------------- #! /usr/bin/perl # 使い方: # require "weather.pl"; # $data=weather; use LWP::Simple; use strict; use encoding 'euc-jp'; use Encode qw/from_to/; binmode STDERR,"encoding(euc-jp)"; sub weather{ my $doc; my $adrs = "http://www.jma.go.jp/JMA_HP/jp/warn/text/27.html"; until($doc){ $doc = get "$adrs"; } from_to($doc,'shiftjis','euc-jp'); $doc =~/<tr><td><pre>(.+)<\/pre><\/td><\/tr>/s; $doc = $1; $doc =~s/」/ /g; $doc =~s/パーセント/%/g; $doc =~s/[0-9]/[0-9]/g; $doc; } 1; my $result=weather; print "$result\n"; ---------------------------

    • ベストアンサー
    • Perl
  • jcode.plの使い方

    最近cgiを始めたばかりの者です。 HTMLでフォームを作り、 FORM action="view.cgi"method="GET" でcgiに渡すようにしました。 CGIで受け取った文字に全角があると %83%8B%83i%83e%83B%83N%83X のような文字化けをします。 調べてみたところjcode.plを使えば 文字化けを回避できるようですがうまく いきませんでした。 質問1.jcode.plを読み込ませるのは 上記のview.cgiで良いのでしょうか。 質問2.require "jcode.pl";といれた後 具体的にどのように受け取ったデータを jcodeに渡せばいいのでしょうか? @data = split(/&/,$ENV{QUERY_STRING}); で@dataに受け取った情報を渡しています。 ご教授頂ければと思います。 よろしくお願いします。

    • ベストアンサー
    • CGI
  • Perlの文字コード変換についての質問です。

    Perlの文字コード変換についての質問です。 ホームページ全体は、UTF-8で作成されています。 そのため、$qsは、どうも、S-JISのようなので、UTF-8に変換して URLデコードさせたいのですがうまくいきません。 文字化けしないで、UTF-8で作成されたページに表示させたいのですがどうすればよいでしょうか? 宜しくお願い致します。 ------------------------------------ $qs = $ENV{'QUERY_STRING'}; use Encode::Guess qw/ shiftjis /; use Encode qw/ decode /; $enc = guess_encoding ( $qs ); if ( ref $enc ) { $utf8 = decode ( $enc->name , $qs ); } $qs =~ tr/+/ /; $qs =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg; print "$qs";

    • ベストアンサー
    • Perl
  • Perl/CGIについて

    #!/usr/bin/perl use CGI; $cgi = new CGI(); $from = $cgi->param('from'); $namae = $cgi->param('namae'); $naiyou = $cgi->param('naiyou'); print "Content-type: text/html\n\n"; # 設定 $sendmail = '/usr/lib/sendmail'; $jcode = './jcode.pl'; $to = 'ha***@***.ne.jp'; #$from = ''; $subject ='名鉄と地下鉄の直通運転'; # 文字コードライブラリの読み込み require $jcode; # メール送信 &jcode'convert(*subject,'jis'); open(MAIL,"| $sendmail -t"); # ヘッダ情報出力 print MAIL "To: $to\n"; print MAIL "From: $from\n"; print MAIL "Subject: $subject\n\n"; # 本文出力 print MAIL " $namae\n\n"; print MAIL " $naiyou\n"; close(MAIL); #確認表示 print " $namae\n"; print " $naiyou\n"; print "メールを送信しました\n"; end #確認表示の所で表示が改行されない。

    • ベストアンサー
    • Perl
  • ver.5.8.8の文字化け

    サーバの移転でアクセスログを変更しているのですが、CGIで苦戦しています。 テキストデータが全て文字化けをしてしまいます・・・。 エキストデータ、ソースは全てSJISです。 perlのバージョンが5.8.8になりましたので、それまで使用していたjcode.plが使えないようです。 require './jcode.pl'; jcode::convert($refer, 'sjis') if ($charset); でエラーになります。 jcode.pm用に use Jcode; Jcode::convert($refer, 'sjis') if ($charset); としてもエラーになります。 これはjcode.pmが入ってないからだと思うのですが、 何か方法はないでしょうか? PHPはわかるのですが、Perlは全然わかりません。 どうか、ご教授をお願いします。

    • ベストアンサー
    • Perl

専門家に質問してみよう