文字列の長さを得る時と部分文字列を取得する時に、ShiftJISでいうところの2バイト文字を2とカウントするような方法を知りたいです。
$src = ’あいう’;
#はてなで’が全角化されるので見づらいとおもいますが「あいう」という文字列です。
#以下同様の理由で「」で括って書きます。
$len = hoge_len($src); => $len = 6
$subst = hoge_substr($src, 0, 3); => $subst = 「あ 」 or 「あ」
$subst = hoge_substr($src, 1, 3); => $subst = 「 い」 or 「い」
のような関数です。
hoge_substr の結果を or で2通り書いていますが、どちらの実装でも構いません。
FAQだと思うのですが今調べる手間が惜しいので質問しています。
できればそのまま使える様なソースが欲しいです。
(SJISに変換した形でunpackして、先頭から2バイト文字境界をチェックしながら切り取っていって、packして文字列に戻せばできそうだ、というぐらいは承知しています)
すみません。1.の回答にコメントした通り、内部コードunicode環境下で実行するためlengthが日本語としての文字数を返すため、lengthでは駄目なのです。
追記:今作ろうとしているものは、utf8プラグマを指定した状態ではよくないことが判り、質問している関数は不要となってしまいました。
純粋に興味として知りたいので質問はこのままにします。
……もう少し、perlの文字コード関連の勉強が必要な様です。
ちなみに、
--
use utf8;
binmode STDOUT, ”:encoding(sjis)”;
$a = ’あいう’;
print length($a).”¥n”;
$tmp = substr(’東京情報大学総合情報学部’, 4, 4);
print $tmp. ”¥n”;
--
上のスクリプトをutf-8でファイルを書いて実行すると(binmode STDOUTは環境によって変える)、
--
3
大学総合
--
という結果になりますね。
http://naoya.dyndns.org/~naoya/mt/archives/000611.html
Perl 5.8 以降においての Unicode 文字列の扱い方 : NDO::Weblog
utf8::encode($title);
printf(”%d¥n”, length($title));
このように エンコードしなおすと utf-8でカウントできるようですが、utf-8って全角、3バイトですよね?
> utf-8って全角、3バイトですよね?
その通りです。
use utf8;プラグマ無しで
--
$a = ’あいう’;
print length($a).”¥n”;
--
を実行すると9が返ってきますね。(ファイルをutf8で書くと、という意味です。)
結局、質問-回答の確認-コメントで、平行して自分で調査しているのと変わらなくなってきました……。
・ファイル自体のエンコードは何で書くか。
・プラグマをどうするか。
・ファイル,標準出力のエンコード指定をどうするか。
この辺をもうちょっと勉強してまた出直してきます。
すみません。決定的な勘違いをしていました。perl v5.8.6で必ず内部コードがunicodeになると思いこんでいました。
今回のプログラムは内部コードutf-8で動かします。(その必要があります)
したがいまして、回答urlにあるlength_sjis関数は誤った長さを返します。
perl標準のlength,substrは以下の様に動作している環境下で、質問の様な動作となるhoge_lenやhoge_substrを探しています。
$src = ’あいう’;
$len = length($src); => $len = 3
$subst = substr($src, 0, 2); => $subst = 「あい」
$subst = substr($src, 1, 2); => $subst = 「いう」