end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転します

perlでutf8等の文字列を扱う

utf8フラグの判定

perlでは、内部的に文字列を Unicode で扱い、その Unicode 文字列には、 UTF8フラグがつくそうです。


utf8フラグの有無は、utf8::is_utf8() で判定することができます。

#!/usr/local/bin/perl

print utf8::is_utf8("ほげ") ? 'UTF-8 Flag' : 'not UTF-8 Flag';
not UTF-8 Flag

use encoding を使うと、UTF8フラグがつくそうです。

#!/usr/local/bin/perl

use encoding 'euc-jp';

print utf8::is_utf8("ほげ") ? 'UTF-8 Flag' : 'not UTF-8 Flag';
UTF-8 Flag


UTF8フラグの有無は、Devel::Peek でも判別することができます。

#!/usr/local/bin/perl

use strict;
use warnings;
use Devel::Peek;

{
    use utf8;

    my $str = "こんにちは!";
    Dump $str;
}

print "\n";

{
    my $str = "こんにちは!";
    Dump $str;
}

FLAGS に UTF8 があれば、UTF8フラグありです。

SV = PV(0x92a2ef8) at 0x92bb6ac
  REFCNT = 1
  FLAGS = (PADBUSY,PADMY,POK,pPOK,UTF8)
  PV = 0x92b3bb0 "\343<略>\201"\0 [UTF8 "\x{3053}\x{3093}\x{306b}\x{3061}\x{306f}\x{ff01}"]
  CUR = 18
  LEN = 19

SV = PV(0x92a2f58) at 0x92bb718
  REFCNT = 1
  FLAGS = (PADBUSY,PADMY,POK,pPOK)
  PV = 0x92b3fc0 "\343<略>\201"\0
  CUR = 18
  LEN = 19

binmode

http://www.r-definition.com/program/perl.htm
↑によると...

srcをutf8 で書いてある場合、use utf8 を使って、utf8 で書かれてあることを perl に知らせるとともに、入出力の文字コードを binmode で指定する必要があります。

例えば、Shift-JIS での入出力する場合、次のようになります。

use utf8;
binmode STDOUT, ":encoding(shift_jis)";
binmode STDERR, ":encoding(shift_jis)";
binmode STDIN, ":encoding(shift_jis)";

utf8で入出力する場合、encoding(utf8)ではなく、:utf8 を使うそうです。

use utf8;
binmode STDOUT, ":utf8";
binmode STDERR, ":utf8";
binmode STDIN, ":utf8";

ちなみにsrcをutf8以外で書く場合、use encoding を使用します。

use encoding "shift_jis";
binmode STDERR, ":shift_jis";
# binmode STDOUT, ":shift_jis";
# binmode STDIN, ":shift_jis";

※use encoding すると、自動的にそれと同じ文字codeが STDOUT と STDIN に適用されるそうです。

Encodeモジュール

次のエントリを参考にさせていただきました。

Encode.pm でよく使うdecode(), encode()は 簡単に言うと
次にように説明できると思います。

decode
文字列にUTF8フラグを付加する。例: decode('UTF-8',$str), decode('eucjp',$str)
encode
UTF8文字列からUTF8フラグを取り除く。例: encode('UTF-8',$str), encode('eucjp',$str)

サンプルコードは次のurlを参考にすると、いいかも