• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Perl 文字コードについて)

Perl 文字コードの問題とは?

このQ&Aのポイント
  • Perlにおいて文字コードに関する問題が発生しています。UTF-8を指定して本文を送るためのコードを書いたところ、本文は文字化けせずに送ることができましたが、件名が文字化けするようになりました。
  • 調査した結果、本文と件名のエンコード方法が異なることが原因であることがわかりました。本文ではMIMEエンコードを使用しているため、パソコンとスマホの両方で文字化けせずに表示されますが、件名では正しいエンコード方法を見つけることができず、パソコンでは文字化けしてしまいます。
  • 件名がパソコンとスマホの両方で文字化けしないようにするには、適切なエンコード方法を見つける必要があります。また、本文はUTF-8で送るようにすることで文字化けを回避することができます。

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

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

$subject = Encode::encode('MIME-Header-ISO_2022_JP', $subject); だけでいい($sibjectは、この時点で「Perl内部文字コード」になっていると想定) encodeは「Perlの内部表現文字コードの文字列を、指定文字コードにエンコードする関数」である。 decodeは「指定文字コードの文字列を、Perlの内部表現文字コードにデコードする関数」である。 したがって「encodeからの戻り値をもう一度encodeに渡す」ってのは「間違った使い方」である。 Perlでは「入力から受け取った文字列をdecode関数で、Perl内部表現の文字列にして、Perlで処理して、encode関数で、出力したい文字コードに変換して、そのまま出力する」のが鉄則。 なので「encodeした物をまたencodeする」とか「decodeした物をまたdecodeする」ってのはやっちゃいけない。 なので「UTF-8の文字列を、ISO-2022-JPのMINE文字列にする」って場合は my $subject = UTF-8の入力から何か受け取る; //受け取った文字列をUTF-8だと思ってPerl内部表現に変換 $subject = decode('UTF-8',$sibject); //Perl内部表現の文字列をISO_2022_JPでMIMEエンコードする $subject = encode(''MIME-Header-ISO_2022_JP',$sibject); と言う処理になる。 一方「リテラル文字列」をメールタイトルにする場合、リテラル文字列は「最初からPerl内部文字コード」になっているから //最初からPerl内部表現の文字列になっている my $subject = '固定のリテラルな文字列'; //Perl内部表現の文字列をISO_2022_JPでMIMEエンコードする $subject = encode(''MIME-Header-ISO_2022_JP',$sibject); と言う処理になる。 ここで注意しないとならないのは「文字コードを直接は変換できない」って事だ。一旦「Perlの内部表現の文字コード」を経由しないとならないのだ。 Perlでは「シフトJIS→ISO2022JP」と言う直の変換は出来ない。「シフトJIS→Perl内部文字コード→ISO2022JP」と言う変換になる。 そして「何かの文字コード→Perl内部文字コード」を行なうのが「decode関数」であって、「Perl内部文字コード→何かの文字コード」を行なうのが「encode関数」である。

r-h-a-o
質問者

お礼

回答ありがとうございます! すごくわかりやすい説明でようやく理解もできました。 おそらく今までデコードとエンコードの仕組みがしっかり理解できていませんでした。 まだ100%理解できたかと言われたらあやしいですが、 だいたい理解できさらに、解決できました!! 本当にありがとうございました!!

その他の回答 (1)

回答No.2

因みに「Perl内部文字コード」が「どんな文字コード」になっているかは「環境依存」なので、何になっているかは誰にも判らない。 「Perlの本体」がインストールされているサーバの設定ファイルか何かに「ソースコード内の漢字コードは○○である」って定義されている筈。 Encodeクラスのencode関数、decode関数は、この「Perl本体のシステム設定の内容」に合わせて、文字コードの変換を適切に行なっている。

r-h-a-o
質問者

お礼

ありがとうございました!

関連するQ&A