【Perl】UTF-8関連のメモ
PerlスクリプトをUTF-8の文字コードで書くときのメモです。今現在はUTF-8で書くようにしていますが、ときどき文字コード関連の処理を忘れちゃうのでメモしておきます。
サンプルスクリプト
下記コードはUTF-8で書いてます。OSはWindowsなので文字コードはcp932(Shift_JISの拡張)です。
#!/usr/local/bin/perl
# -*- Encoding: UTF-8 -*-
use strict;
use warnings;
my $encoding = "UTF-8";
my $message = "このファイルの文字コードは[$encoding]です"; # 文字コードはUTF-8
# 標準出力はcp932(Shift_JISの拡張)なので文字化けする
print "$message\n";
exit;
コマンドプロンプトで実行したら文字化けします。
C:\home>perl encoding_utf8_0.pl
縺薙・繝輔ぃ繧、繝ォ縺ョ繧ィ繝ウ繧ウ繝シ繝峨・[UTF-8]縺ァ縺・
文字化け回避する
Encodeモジュールを使用して、encode関数とdecode関数をロード。標準出力に書き出す前に文字コードを調整して出力すれば文字化けは回避できる。
#!/usr/local/bin/perl
# -*- Encoding: UTF-8 -*-
use strict;
use warnings;
use Encode qw/encode decode/;
my $encoding = "UTF-8";
my $message = "このファイルの文字コードは[$encoding]です"; # 文字コードはUTF-8
$message = decode('utf8', $message); # UTF-8 -> (内部文字列)
$message = encode('cp932', $message); # (内部文字列) -> cp932
print "$message\n"; # -> 文字化けしない
exit;
コード量は増えるけど文字化けは回避できる。
C:\home>perl encoding_utf8_1.pl
このファイルの文字コードは[UTF-8]です
utf8プラグマを有効にする
utf8プラグマにすれば文字列リテラル(ソースコードの中に書かれた文字列)を内部文字列に自動デコードしてくれる。Encodeモジュールのdecode関数は使わなくなってので消してます。
#!/usr/local/bin/perl
# -*- Encoding: UTF-8 -*-
use strict;
use warnings;
use utf8; # 文字列リテラルを内部文字列に自動デコードしてくれる(他にも機能あり)
use Encode qw/encode/;
my $encoding = "UTF-8";
my $message = "このファイルの文字コードは[$encoding]です"; # (内部文字列)
$message = encode('cp932', $message); # (内部文字列) -> cp932
print "$message\n"; # -> 文字化けしない
exit;
binmode関数で標準出力の文字コードを指定する
binmode関数を使って標準出力に書き出すときに特定の文字コード(ここではcp932)へエンコードするように指示しておく。Encodeモジュールの関数を使わなくなったのでuseしない。
#!/usr/local/bin/perl
# -*- Encoding: UTF-8 -*-
use strict;
use warnings;
use utf8;
binmode STDOUT, ":encoding(cp932)"; # 標準出力にprintするときcp932に自動エンコード
my $encoding = "UTF-8";
my $message = "このファイルの文字コードは[$encoding]です";
print "$message\n"; # -> 文字化けしない
exit;
端末の文字コードを自動判別
Encode::Localeモジュールを使うことで、端末の標準入出力を自動判別させることができることを最近知りました。binmode関数で文字コードを指定するときに「console_out」とすれば自動判別してくれます。
#!/usr/local/bin/perl
# -*- Encoding: UTF-8 -*-
use strict;
use warnings;
use utf8;
use Encode::Locale; # 標準入出力の文字コードを端末のものに合わせる
# 標準出力にprintするとき端末の文字コードに自動エンコード
binmode STDOUT, ":encoding(console_out)";
my $encoding = "UTF-8";
my $message = "このファイルの文字コードは[$encoding]です";
print "$message\n"; # -> 文字化けしない
exit;
Encode::Localeモジュール便利ですね。サンプルスクリプトは標準出力に対する命令しかないですが、標準入力、標準エラーの文字コードも自動判別させられる。
過去の同じ日の記事一覧
Michael SchwarzenbergerによるPixabayからの画像を使用しています。
ディスカッション
コメント一覧
まだ、コメントがありません