前回のエントリーでPerlで文字列を扱う場合は内部文字列に変換しなくてはいけないことを学びました。
Contents
内部文字列を使うわけ
ところで何のために内部文字列に変換するのでしょうか。実はPerlは内部で内部文字列として変換して初めて、文字列として認識できるようになります。
具体的には文字列の長さをはかったり、正規表現でパターンマッチを行うなどのことができるようになります。逆に言うと内部文字列に変換しないと正確な文字列の長さをはかったり、正規表現のパターンマッチを行うことができません。
これは日本語がマルチバイトであることに起因しています。
例えば下記のソースをコマンドラインで実行し、引数に「本日は晴天なり」を与えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
use strict; use warnings; use Encode; use Data::Dumper; my $byte_str = shift; //内部文字列 my $internal_str = decode('UTF-8',$byte_str); my $length = length $internal_str; print $length ."\n"; //長さ7 if( $internal_str =~ /$internal_str/) { print "Match\n"; //Matchが表示される } //use utf8をつけていないため、バイト文字列扱い my $internal_str2 ='本日は晴天なり'; my $length2 = length $internal_str2; print $length2 ."\n"; //長さ21 if( $internal_str =~ /$internal_str2/) { print "Match\n"; //Matchが表示されない } |
上記のソースを実行してみるとわかるようにバイト文字列をそのまま扱った場合(上記の$internal_str2のケース)では文字列や正規表現のパターンマッチが正確ではありません。
あまりないケースですが、ファイル名に文字列が入っているケースでも内部文字列に変換をしてあげないと正常に入出力を行うことができません。
文字コードの変換
文字コードの変換を行う際は、内部文字列を一旦他の文字コードのバイト文字列に変換して行います。
例えばUTF8の文字列を読み込んで、SHIFT_JISにする場合、
UTF8バイト文字列 → 内部文字列 → SHIFT_JISバイト文字列
というようなステップを踏む必要性がでてきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
use strict; use warnings; use Encode; use Data::Dumper; my $byte_str = shift; #内部文字列に変換 my $internal_str = decode('UTF-8',$byte_str); #Shift_JISバイト文字列に変換 my $shitf_jis_byte_str = encode('Shift_JIS', $internal_str); #上記の変換はややメンドイので下記のように一気に書くこともできます。 my $byte_str = shift; from_to($byte_str,'UTF-8','Shift_JIS'); |
[…] Perlの文字コードに関して その2 […]