今まで全てのPerlをjcode.plを使って日本語化してきました。
長年根本の構造をきちんと理解せず、jcode.plは呪文のように最初に宣言して使用してきたため、現在文字化け対策をするため、今回Encodeモジュールを使って日本語変換を行うための方法が分からず困っています。
formから送信されてきたものを変換するため、
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;#ここは状況に応じて変えてます
}
として最初に一括して変換してやり、
ウェブ上で表示させるときは
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
を指定してそのまま表示、
メールなどでは
&jis("Subject: $sub"); print AAA "$msg\n";
sub jis { $msg = $_[0]; &jcode'convert(*msg, 'jis'); }
などとして出力してきました。
これらをEncodeモジュールを使って書き換えたいのですが、参考に
http://digit.que.ne.jp/work/wiki.cgi?Perl%E3%83% …
このページを読んだのですが、perlの根本が理解できていないので、どこをどうしていいのか分かりません。
上のような形式をEncodeモジュールを使って書き換えるとすればどのようにすればいいのでしょうか。
(どう聞けばいいかも分からないので、うまく伝えられたか不安ですが)
No.4ベストアンサー
- 回答日時:
#1です
ああ、その書き方では駄目です。
Base64 エンコードする必要があるのはあくまでも日本語などの『非ASCIIのデータ』のみですから
&jis("$sub"); &base64("$msg"); print AAA "Subject: $str\n";
となります("Subject:"の部分はエンコードしちゃ駄目)
ですから正確を期すならば sub base64 も
sub base64 {
use MIME::Base64;
$str = $_[0];
if($str =~ /[^!-~\s]/){
$str = encode_base64($str, "");
$str = '=?iso-2022-jp?B?' . $str . '?=';
}
}
としておけば完璧でしょう(サブジェクトにASCII以外の文字が含まれている場合のみ Base64 エンコードを行います)
return $str; に関して
コメントアウトしないと動作しないとの事ですが…
そうですね。その関数の呼び出し方だとそうなるかもしれません。
最初見た時は何気に見過ごしていたのですが、今回改めて眺めてみて
&jis("Subject: $sub"); &base64("$msg"); print AAA "$str\n";
この一行の意味がしばらく理解できなかったです。何故?何故変数名がコロコロ変わってるの??この変数はどっから湧いてきた???って
strict モジュールを用いて必ず変数宣言する癖がついて幾星霜。こんなperl4チックなスクリプトは久しぶりだったもので油断しました。
とりあえず今回の質問とは全然関係ないのでスルーしても良いのですが、今後も perl を触り続けるのならば、上記のようなソースは NG となりますので、一度キチンと基本から学んでおいた方が良いかもしれませんよ?(大きなお世話ですが)
興味があるようでしたら、 use strict みたいなワードでグーグル先生に聞いてみましょう。
PS
print AAA "Content-Type: text/plain\; charset=\"ISO-2022-JP\"\n\n\n";
↑改行しすぎでコーヒー吹いた
改行は2個で良いんですよ、2個で↓
print AAA "Content-Type: text/plain\; charset=\"ISO-2022-JP\"\n\n";
ありがとうございました
無事正常に稼働するようになりました。
>何故?何故変数名がコロコロ変わってるの??この変数はどっから湧いてきた???って
>strict モジュールを用いて必ず変数宣言する癖がついて幾星霜。
perlを最初に触ったときは、フリーのスクリプトを紙に起こし、それを睨めっこして覚えました。
もちろんプラスして入門書も使いましたが、小難しいことは書いてません。
そのため本当の基本が分かってないので$_とかといったいわゆる「それ」という使い方が難しく、確実に”その”データを取るため、こうやっています
foreachとかも@データを各行ループさせるときにもわざわざ毎回固有変数名をつけてやってたりします
格好悪いですし、myとかの使い方もよく分かってないため、長いスクリプトになるとかえってわけ分からなくなるので、何とか直したいのですが・・・入門をネットで探したらあまりにも入門過ぎるし、それ以上を探すと自分のレベルを遙か超えた内容ばかりでなかなか次のステップへ上がるための本やサイトが見つからなくて困ってます
>use strict みたいなワードでグーグル先生に聞いてみましょう
ありがとうございます。
どこでどう学んでいいのか分からないので、この文字を参考に引いてます
>改行は2個で良いんですよ、2個で
何個いるのか理由もさっぱり分かっておりません
このコードはもう何年前になるでしょうか。
10年以上前だったか、perlを初めて触ったときに参考にしたスクリプトを意味も分からずそのまま使ってましたので
No.3
- 回答日時:
#1です
>ここのEncodeの中の$valueは$strでいいのでしょうか?
>$subject2を$subとすればいいのでしょうか?
おっしゃる通りでございます。
なんかいろいろとグダグダで申し訳ありません。
んでパールの記述チェックで Prototype mismatch エラーが出たということは、多分 encode って名前のサブルーチンがすでにスクリプト内で宣言されているのではないでしょうか?( sub encode でスクリプトを検索してみてください)Encode モジュールを使用するならばこの名前は使用できませんので、別の名前に置換してやる必要があります。
ちなみに、
>文字化けすることがたびたびある
との事ですが、別にこれは jcode.pl に原因があるわけではなく、スクリプトの書き方に問題が在るためだと思いますよ(多分ですけど)
文字コードを変換するときに incode をキッチリと明示してやればそうそう化ける事などない筈です。
というかそもそも
・フォームを記述した html が Shift_JIS
・スクリプトも Shift_JIS
・スクリプトが吐き出すデータも Shift_JIS
ならば文字コードを変換する必要がそもそも無くなるわけで、論理的に文字化けなど起こる筈もありません(機種依存文字や携帯の絵文字を使われたらその限りではありませんが、これはもうどうしようもないですもん)
まぁそれでも『今更 jcode.pl なんか使ってらんねぇぜ!俺は Encode を使いたいんだYO!』という気持ちも解らないでもありません。そんな場合は Jcode.pm を Encode モジュールのラッパーとして使用するのが一番簡単かもしれないですね(今更そんな事言うなよ!という突っ込みはナシの方向で…)
jcode.pl と同じ感覚で Encode モジュールを使用する事が可能です。
作業その1
require './jcode.pl'; を require './Jcode.pm'; に変更
作業その2
スクリプト内の &jcode' を &Jcode:: に全置換
作業その3
Jcode.pmをサーバにアップ
基本的にこれだけで作業は完了です。
詳しくは Encode モジュールの作者であり、 Jcode モジュールの作者でもある小飼 弾様のサイトを参照なさってみてください。
参考URL:http://openlab.ring.gr.jp/Jcode/index-j.html
非常に丁寧な解説本当にありがとうございます。
試行錯誤しながらもなんとか少しずつ前に進んでいる・・・と思います。
Prototype mismatchの件はおっしゃるズバリのとおりでしたので即解決できました。
それと、
sub jis {
$str = $_[0];
Encode::from_to($value, "shiftjis", "iso-2022-jp");
return $str;
}
は、うまくいかなかったのですが、最後のreturn $str;を#を加えて実質非稼働にしてみたらうまく作動しました。
あとちょっとだけ教えて頂きたいのですが。
日本語変換のおまけで教えて頂いたbase64です。
&jis("Subject: $sub"); &base64("$msg"); print AAA "$str\n";
sub jis {
$msg = $_[0];
Encode::from_to($msg, "shiftjis", "iso-2022-jp");
}
sub base64 {
use MIME::Base64;
$str = $_[0];
$str = encode_base64($str, "");
$str = '=?iso-2022-jp?B?' . $str . '?=';
}
iso-2022-jpに変換したあとbase64に変換しなくてはならないとのことでしたが、上記のようにしてみたところ、
&jis("Subject: $sub"); &base64("$msg"); print AAA "$str\n";
の後ろにヘッダーの続きとして記述してあった
print AAA "Content-Transfer-Encoding: 7bit\n";
print AAA "Content-Type: text/plain\; charset=\"ISO-2022-JP\"\n\n\n";
をひっくるめてメールのbody内に書込まれてしまいました。
sub base64内の最後に
return $str;
を書き加えてみても動作は同じでした
(なぜかsub jis内ではreturn $msg;を加えるとエラーになるのにこちらではなりませんでした)
このiso-2022-jpとbase64への変換の連続技はどのようにしてやればうまくいくのでしょうか。
PS Jcode.pmの件もありがとうございました。ここまで進めてきたので今回はEncodeでやり遂げたいと思いますが、Jcode.pmもあわせて勉強してみたいと思います。
No.1
- 回答日時:
文字化け対策で何故 Encode モジュールを使用するのでしょう?
よくわからないなぁ…?
ユニコードでも扱うとでもいうのでしょうか?
想像で恐縮ですが、ここでは UTF-8 で作成されたフォームからデータを受け取りたいのだと仮定しておきます。
まずは最初におまじないを記述
use Encode qw(from_to encode);
あとは
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;
Encode::from_to($name, "utf8", "cp932");
Encode::from_to($value, "utf8", "cp932");
$in{$name} = $value;
}
これでとりあえず受け取ったデータを Shift_JIS に変換できました。
(正確には CP932 ですけどね。Shift_JIS に変換せても良いけど Unicode => Shift_JIS の変換には色々と問題があるので無難に CP932 をチョイスしました)
Encode にも受け取ったデータを自動で判別する機能は存在しますが、精度があんまりよろしくないのでそれこそ文字化けの原因になります。ですんで例のようにキチンと incode を明示してやる事を激しく推奨です。
メールなどで ISO-2022-JP に変換したいのならば、サブルーチン jis を
sub jis {
$str = $_[0];
Encode::from_to($value, "shiftjis", "iso-2022-jp");
return $str;
}
こんな感じで良いと思うのですが…
ちなみにメールのヘッダ内で使用する日本語は上記のルーチンだけでは不正な書式になります。
ISO-2022-JP に変換した後にBASE64エンコードしてやる必要があります。
で、一応 BASE64 エンコードするサブルーチンの例も記述
sub base64 {
$str = $_[0];
$str = encode_base64($str, "");
$str = '=?iso-2022-jp?B?' . $subject2 . '?=';
return $str;
}
記述例まで書いて頂き、ありがとうございます。
>文字化け対策で何故 Encode モジュールを使用するのでしょう?
>よくわからないなぁ…?
文字化けすることがたびたびあるので対策方法を探しておりましたらjcode.plは古いから使わない方がいいというページがわんさか出てきたので、サーバーもperlが5.8なのでならば日本語化にはEncodeを使うほうがいのかなぁ・・・と、ただそれだけの理由です。
目的は、入力されたもの送信するもの全てが、できる限り(できることなら全く)文字化けしないようにしたいのです。
とくにEncodeにこだわってはいません。
早速教えて頂いた内容を元にやってみました。
追加でお尋ねしたいのですが、
$str = $_[0];
Encode::from_to($value, "shiftjis", "iso-2022-jp");
return $str;
ここのEncodeの中の$valueは$strでいいのでしょうか?
$str = '=?iso-2022-jp?B?' . $subject2 . '?=';
の部分ですが、質問に書いた形ですと$subject2を$subとすればいいのでしょうか?
あとパールの記述チェックをしたところ
Prototype mismatch: sub main::encode ($$;$) vs none at test.cgi line 181.
test.cgi syntax OK
とでてきました
エラーの場所は、エラーに表示されたラインから推測して
$msg = $_[0];
Encode::from_to($msg, "shiftjis", "iso-2022-jp");
retern $msg;
のところだと思います。
これはどう解決すればいいのでしょうか。
ネットでももちろん調べてみたのですが、どう解決していいのか分かりません
サーバーのperlバージョンは5.8.*です
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP PHPでCookieを使った訪問回数について 1 2023/05/28 14:10
- HTML・CSS ボタンをクリックした時に、入力フォームのすぐ下部に、「入力欄が空白です」というテキストメッセージが表 1 2022/04/27 16:25
- PHP 入力した部分を表示させたまま(保持)するにはどうすれば良いでしょうか? 1 2023/01/25 11:14
- JavaScript 入力フォームの javascript で メールアドレスの正規チェックをを行い、ボタンをクリックして 2 2022/04/27 16:06
- PHP php ログイン 1 2022/11/01 00:24
- JavaScript 2段階プルダウンで1段階目の選択を終えた後に選択ボックスを見えなくしたい 2 2022/07/05 21:58
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- PHP PHPでユーザー情報を入力して簡易ログイン機能をつくってみたのですが 1 2023/05/29 08:51
- JavaScript Javascriptが機能せず原因が分からないので教えて頂きたいです 3 2023/06/04 14:50
- JavaScript sessionStorageを調べています。 1 2023/06/20 12:41
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
メール(iso-2022-jp-2)のデコ...
-
Perl:ファイル名だけ文字化けする
-
pythonエラー
-
MIMEでエンコードされたMailのS...
-
CASLIIの数値データ入出力
-
CSVファイルの中で、「 , 」カ...
-
英数字のみ全角から半角に変換
-
Excel VBAでPDFファイルをMicro...
-
Accessで日付や数値を全角で表...
-
データにカンマが入ったCSVデー...
-
EXCELからCSVにすると余計なカ...
-
「何とかで始まり、何とかで終...
-
エクセルで数値を全角文字(カ...
-
CString Format にて全角空白文...
-
住宅にカナを入力する際に丁目...
-
VBA EXCEL あるセルの中の一...
-
csvデータのダブルクォーテーシ...
-
正規表現で、特定の文字列を含...
-
各項目がダブルクォーテーショ...
-
ハングルを日本語に置換
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
pythonエラー
-
Perl:ファイル名だけ文字化けする
-
IMAP4でsubjectが検索ヒットしない
-
URLエンコードされたデータを戻...
-
1つのサイトで文字コードが混在...
-
perlの日本語文字コードはどう...
-
テキストファイルから日本語部...
-
メール(iso-2022-jp-2)のデコ...
-
jisコードで16進数の『3c』か...
-
「繝・せ繝・」となる文字化け
-
Encodeモジュールで日本語化したい
-
jcode.pmでconvertできない
-
quoted-printableのアルゴリズム
-
Encode.pmで文字コードの判別
-
CASLIIの数値データ入出力
-
BASP21によるbase64のデコード...
-
Perlでのメール本文の解析について
-
PerlでJavaScriptを作成してい...
-
CSVファイルの中で、「 , 」カ...
-
何故、日本は未だに数字を3桁...
おすすめ情報