いつもお世話になっております。
下記の構文で分からないところがございます。
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で質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
BASP21によるbase64のデコード...
-
Perl:ファイル名だけ文字化けする
-
CSVファイルの中で、「 , 」カ...
-
英数字のみ全角から半角に変換
-
エクセルで数値を全角文字(カ...
-
文字コードの%E3%80%とは何です...
-
住宅にカナを入力する際に丁目...
-
VBA 文字に半角が含まれて...
-
EXCELからCSVにすると余計なカ...
-
IEからEdgeへの移行に伴うIMEの...
-
CSVの定義
-
VBA 置換文字がみつからない時
-
Excel VBAでPDFファイルをMicro...
-
各項目がダブルクォーテーショ...
-
Excelについて質問です。 セル...
-
Accessでのグループ化で全角・...
-
テキストボックスの文字列を置...
-
EXCEL警告「置換対象のデータが...
-
ダブルコーテーションの置換
-
エクセルの検索が正しくできな...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
1つのサイトで文字コードが混在...
-
BASP21によるbase64のデコード...
-
IMAP4でsubjectが検索ヒットしない
-
jcode.pmでconvertできない
-
Perlでのメール本文の解析について
-
CASLIIの数値データ入出力
-
pythonエラー
-
MIMEでエンコードされたMailのS...
-
quoted-printableのアルゴリズム
-
外部サイトの内容の取得
-
Encodeについて
-
標準入力からのutf-8→euc-jpで...
-
Perl 文字化け
-
正確に日本語にマッチさせるに...
-
UTF-8の「~」をsjisにencodeす...
-
Encode.pmで文字コードの判別
-
jisコードで16進数の『3c』か...
-
urlエンコード後の文字コードは...
-
検索キーワードのデコードについて
-
CGIでメールを送る際に文字...
おすすめ情報