

いつもお世話になっております。
下記の構文で分からないところがございます。
use Encode;
use Encode::Guess qw/euc-jp shiftjis 7bit-jis/;
use Encode qw/decode/;
$enc=guess_encoding($x);
if(ref $enc){$x=decode($enc->name,$x);}
実はあるテキストに載っていたコードなのですが、解説には
文字データのコードが分からない場合は、Encode::Guessを使います
としか書いてありません。
2行目は、文字コードのリストをqwで囲んであると分かりますが
3行目は、なぜdecodeをqwで囲む必要があるのでしょうか。
decodeメソッドを使うと意味だとすると、必要ないように思ってしまい
ました。大きな勘違いをしているかもしれません。
最後の2行は、文字コードを推測して、そのあとが分かりません。
いつも初心者質問で申し訳ありませんが、よろしくお願いいたします。
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
まず情報の訂正から。
> Encode::decode とか Encode::encode のように修飾した名前を使わなければならないところで
> decode や encode のように記述できるようになります。
と書きましたが、Encodeの場合はちょっと事情が複雑でした。
use Encode; とした場合
Encode::decode のような修飾なしで関数を呼び出せる。
use Encode qw(decode); とした場合
qw()の中に書かれた関数は修飾なしで呼び出せるが、
それ以外の関数は修飾した名前でないとエラーになる。
つまり上の例の場合、
deocde(ほげほげ)→OK
encode(ほげほげ)→NG
Encode::encode(ほげほげ)→OK
のようになります。
わたしが良く見るモジュールでは前回書いたように、
qw で後に並べた名前だけ修飾なしで使えるというものがほとんどだったと思います。
次に、#1の補足にある
> 結果は
> こんにちは
> shiftjis or utf8
>でした。
geuss_encodingがこれを返したということは、
shiftjis か utf8 のどちらかだと思われるが情報が少なくて決定できない。
ということです。
Encode::Guess によるエンコーディングの判定は
Jcodeのものよりもより汎用的にできているため、
データが少ない場合の推測結果があまり正確でなかったり、
今回のように決定できないということになったりします。
もし日本語のエンコーディングだけ推測できればいい
ということであれば、Jcodeを使ったほうが自動判定は成績が良い傾向にあります。
http://blog.livedoor.jp/dankogai/archives/507373 …
あたりにちょっと事情が載っています。
対策としてはできるだけ長い文字列を与えて判定させるようにするくらいですかねえ。
sakusaker7さん、アドバイスありがとうございました。
文字列が少ないと判別に失敗したり、複数行ある場合、1行ずつ
異なるコードと判定したりするようですね。
推測(guess)できなかったときの処理をきちんとしておく必要が
あるという結論でしょうか。
Encodeについては、以前にもこのサイトで質問させて頂きました。
私自身は、HTML担当でPerlは勉強中です。文字化け対策としては
HTMLも、Perlプログラムも全てutf-8で保存する、コンテントタイプ
ヘッダで宣言もするというのが一番の解決と思っています。
それでも化けることがあると聞いたことがありますが・・・
もっと勉強しないとスキルアップできませんね。
お忙しいところ誠にありがとうございました。
No.1
- 回答日時:
> 3行目は、なぜdecodeをqwで囲む必要があるのでしょうか。
> decodeメソッドを使うと意味だとすると、必要ないように思ってしまい
> ました。大きな勘違いをしているかもしれません。
ためしに、
> use Encode qw/decode/;
のqw/decode/ の部分を削除して実行してみてください。
> if(ref $enc){$x=decode($enc->name,$x);}
の部分で、mainパッケージにdecodeなんて関数ないよという
感じのエラーになるはずです。
つまり、use Encode の後ろにリストで関数名を渡しておくと、
本来なら
Encode::decode とか Encode::encode のように修飾した名前を使わなければならないところで
decode や encode のように記述できるようになります。
> 最後の2行は、文字コードを推測して、そのあとが分かりません。
> $enc=guess_encoding($x);
> if(ref $enc){$x=decode($enc->name,$x);}
guess_encodeingが返しているのは、推測によって得られたエンコーディングの情報です。
そして、$enc->name は何かというと、その結果のエンコーディング名です。
つまり、'euc-jp' とか 'utf-8' のようなものです。
ですのでdecodeの第一引数として渡すことができるわけです。
また、ref $enc のようなチェックをしているのは、
適当なエンコーディングに決められなかった場合に、guess_encodingの戻り値は
リファレンスではないので、それによりdecode可能かどうかを判定しているためです。
#Encode::Encodingのオブジェクトじゃなかったかなあ。
ですので、decodeのところはオブジェクトのそれを活かして
if(ref $enc){$x = $enc->decode($x);}
でも同じ結果になったと思います。
この回答への補足
こんにちは。質問者です。
やっと実験できました。下記のように書いてアップロードしてみました。
結果は
こんにちは
shiftjis or utf8
でした。
use Encode qw/decode/; → これは、なくても動いたようです。
でも内容については、実際にいろいろ試してみて
やっと分かってきました。
お騒がせして申し訳ありません。ありがとうございました。
use Encode;
use Encode::Guess qw/euc-jp shiftjis 7bit-jis/;
my $x="こんにちは";
my $enc=guess_encoding($x);
if(ref $enc){$x=decode($enc->name,$x);}
print <<END;
Content-type: text/html; charset=utf-8
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>サンプル</title>
</head>
<body>
<p>$x</p>
<p>$enc</p>
</body>
</html>
END
sakusaker7様
丁寧な答ありがとうございます。
decodeメソッド、encodeメソッドは、use Encode;
と記述すれば使えるのではないかと思っていました。
例えば
use Encode;
my $data="shift_jisで書かれた文字列";
$data=decode("shift_jis",$data);
$data=encode("utf-8",$data);
というような場合とは異なるということでしょうか。
ダブルコロンは、以前
use CGI;
$CGI::POST_MAX=1024;
で使用したことがありますが、こっちは理由がよく分かりました。
今回の場合は、「?」だったのです。
中途半端なコメントで申し訳ありません。
睡魔のため頭が働かないので、また明日改めてコメントします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Perl Perl の外部モジュールの利用方法 3 2022/07/10 18:34
- JavaScript フォームが空欄の時にフォームの外をクリックすると、エラーが出るコードを調べています。 1 2023/06/25 11:51
- その他(プログラミング・Web制作) 文字コード及びフォントに関する次の記述を読み,適切なものをすべて選べ。 ASCIIとは,英数字だけを 4 2023/01/11 19:10
- その他(プログラミング・Web制作) pythonのこのエラーがわかりません 3 2022/11/16 14:54
- Excel(エクセル) 指定文字列が該当するA列をアクティブセルにするには 3 2022/08/17 13:18
- JavaScript セレクトを全て選択されていないと、文字によるエラーメッセージを表示させるコードを調べています 2 2023/06/22 15:48
- JavaScript sessionStorageを調べています。 1 2023/06/20 12:41
- PHP phpのメールフォームの完了画面でメール受信のコードを書いています。 1 2023/05/31 11:39
- PostgreSQL PostgressからMySQL(MariaDB)へ構造を変更する際のTimestamp等について 2 2023/04/04 12:09
- その他(プログラミング・Web制作) 【Python初学者】以下コードについて教えていただきたいです 4 2023/04/19 13:01
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
pythonエラー
-
BASP21によるbase64のデコード...
-
CSVファイルの中で、「 , 」カ...
-
住宅にカナを入力する際に丁目...
-
エクセルで数値を全角文字(カ...
-
Excelについて質問です。 セル...
-
VB.net、テキストボックス入力...
-
Excel VBAでPDFファイルをMicro...
-
VBA 文字に半角が含まれて...
-
CSVの定義
-
IEからEdgeへの移行に伴うIMEの...
-
「一角」って何でしょうか
-
全角英数字の必要性が理解できない
-
SQLのデータで半角カナを全角に...
-
WORDで改ページすると時々グレ...
-
CString型からdouble型への変換
-
文字コードの%E3%80%とは何です...
-
英数字のみ全角から半角に変換
-
マクロを使ってフォルダー内に...
-
COBOL・全角判定
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CASLIIの数値データ入出力
-
「繝・せ繝・」となる文字化け
-
Perl:ファイル名だけ文字化けする
-
IMAP4でsubjectが検索ヒットしない
-
quoted-printableのアルゴリズム
-
1つのサイトで文字コードが混在...
-
jisコードで16進数の『3c』か...
-
BASP21によるbase64のデコード...
-
エンコード方法についての質問
-
文字コードについて
-
Perlでのメール本文の解析について
-
メールを文字化けしないように...
-
文字コード? 推奨UTF-8?
-
PerlでJavaScriptを作成してい...
-
メール(iso-2022-jp-2)のデコ...
-
MIMEでエンコードされたMailのS...
-
Jcodeモジュールの代わりにjcod...
-
標準入力からのutf-8→euc-jpで...
-
Lite.pmを使ったメールで文字化け
-
Perl+UTF8で文字化け
おすすめ情報