perlには文字列の長さを得るためのlength関数が有ります。
my $string = 'string';
print length($string);
=>6
ここまでは分かりやすいですね。
しかし、length関数はutf8フラグが立っていると、バイト数ではなく、文字数を数える点に注意が必要です。また、use bytes指定で、バイト数を数える様に変更する事が出来ます。
use utf8;
my $string = '文字列のデータ'; # use utf8指定が有るのでソース上の文字列はutf8フラグが付く
print length($string);
print "\n";
use bytes;
print length($string); # use bytes指定は、文字数ではなく、バイト数を数えろという指定
print "\n";
=>7
=>21
最初は長さを7と数え、次は21と数えました。
これは文字数とバイト数の差です。
漢字やひらがな・カタカナの様な多バイト文字を扱う時は注意が必要です。
utf8フラグと、use bytesの関係を表にまとめてみました。漢字やひらがなの様に1文字≠1Byteとなる文字コードでは、必ず下記の関係を意識しながらコーディングする必要が有ります(扱うデータが全てUS-ASCIIの様に1文字=1Byteとなる場合は全然気にする必要は有りませんが)。
| パターン | utf8フラグ | use bytes | 文字列のカウント |
|---|---|---|---|
| 1 | 有り | 無し | 文字数 |
| 2 | 有り | 有り | バイト数 |
| 3 | 無し | 有り | バイト数 |
| 4 | 無し | 無し | バイト数 |
この様なutf8フラグとuse bytesの組み合わせによって挙動が変わる(つまり、文字数を数えるのか、バイト数を数えるのかが変わる)関数にはchr, ord, substr, index, rindexが有ります。
2010/4/11追記
注意事項として、use bytesを使うとバイト数が得られますが、バイト数をカウントしたい場合は何らかのPerlの外部との入出力を伴う場合が多いと想定されます(ファイルに書き込む長さが欲しいとか)。この様な場合、必ずEncodeモジュールで文字コードを指定して変換すると思いますので、use bytesよりEncode::encode()を使って正しい文字コードに変換した上でバイト数をカウントする方が適切な場合が多いと思われます。

コメントする