utf8移行と自分メモその2

2007/1/10 [23:36:02] (水) 天気

で、趣味は読書SNSは、utf8環境となった、のかな。今まで全部eucだったんで、実際どんなところに影響するのかまだ把握できてない。jisにsjisにeucにutf8に、と。4つも違う文字コードがあるのっておかしいんじゃね。と語尾をちょっと上げてみる。utfに収斂されていく勢い、と思ってもどこかのベンダーが妙な拡張してまた違うコードが出てきたりして。


てのはともかく。

今さらだけど perl5.8は。

出入りするデータはただのバイト列として扱う。utf8を扱うにはutf8フラグを立ててperlにこれはutf8として扱ってね、と教える必要がある。encoding とか use utf8 なんかがフラグ立てに使われるらしい。

今後推奨されるのはスクリプトをunicodeで書いて use utf8 する書き方だそうだ。そうするとスクリプト内の文字列には utf8フラグがつくのでなにかと便利、なのかな。


わたしが混乱したところ。

文字コードとしてのutf8とperlのutf8フラグは「また別」。


postgresqlから取り出したばかりのutf8の文字「根性」とスクリプト内のutf8フラグの立ったutf8文字列「根性」をそのまま比較しても意図した通りにはならない

取れたての「根性」 != スクリプト内の「根性」

となる。取れたての「根性」にはutf8フラグが足りないのだ。

Encode::decode(’utf8’,「根性」)などと「根性」にutf8フラグをつけてやれば

「根性」==「根性」

となる。それじゃせっかくだしprintしてみるか、と「根性」を出すと wide char うんぬんと脅される。utf8フラグのついた文字列を表に出すとケチをつけられるのだ。

Encode::encode(’utf8’,「根性」)とやって今度はutf8フラグを落としてやると警告は出なくなる。

勘違いしてたんだけど、utf8フラグというのはperlの内部のフラグ。

これをくっつけて出力するわけではない。

リダイレクトすれば普通に「文字コード」utf8で書き込まれるだけ。データベースへのinsertも同じこと。


Encodeのdecodeとencodeてのは。

「jis、sjis、euc、utf8」で書かれた文字列にutf8フラグをつけるのがdecode(その文字列がどのコードで書かれているのか教えてutf8フラグをつける)

utf8フラグがついてしまえば自由自在でごにょごにょ。その後表に出すような時にエクセルで読むからシフトJISでお願いと言われたらencodeで「jis、sjis、、euc、utf8」に変換する。この時utf8フラグも落とすので上のwide char うんぬんの警告は出ない。

decodeでutf8フラグをつけて、内部処理が終わったらencodeでutf8フラグを落としましょう、ということかな。


unicodeで書かれたスクリプトにutf8フラグをつけると変数名に「日本語」が使えたりする。


use utf8

my $気合=10:

while($気合--){

print Encode::encode(’utf8’,’喝’);

}


喝喝喝喝喝喝喝喝喝喝


となる。スクリプトがわかりやすいぞ。


my $除夜の鐘=108;

my $鐘の音=’ゴーン’;

my $おやじギャグ=’カルロス’;

というのを見るだけでなにをしようとしてるのか分かるでしょ。


て、ネタを続けるのはうるさい、な。


postgresqlからselectなりで読み込んだらdecodeする必要がある(全部が全部というわけじゃないけど)。スクリプトのあちこちに散らばるselectを探していちいちdecodeなんちゃらと書き込むのは勘弁してほしい。ので検索してみると、decode encode のための wrapperを自前で作るひともいたけど、perl DBI DBD-Pgと postgreql だと connectしたら

dbh->{pg_enable_utf8}=1

で text と varchar のフィールドから取り出すものに関してutf8フラグをつけてくれる。ありがたい話だ。

今までのスクリプトをほとんどそのまま使える。ただ、wide char うんぬんの警告がうるさいこともあるんで、utf8::is_utf8(文字列) でutf8フラグがついてるかどうかをチェックするようにした。


cgiのformでの文字コードの扱いでもひっかかる。

いやutf8にしたいんだけど、と。

文字コードを変換するためにEncode::encodeを使うにはEncode::decodeでutf8フラグをつけてやる必要がある。ところがdecodeにはその文字列がどの文字コードで書かれているか教えてやる必要がある。

冒頭に書いたように流れてくるコードはjisだなんだで4種類。どのコードなのかわからないので推測するしかない。文字どおりGuessというのがあるんだけど、試しに「アイウエオ」とだけかいたファイルをeuc、sjis、jisの3種類用意して試したところ’shiftsiji or euc’というエラーで死ぬ。ネットで見てると、Guessはできるだけつかわないでね、と。弱ったなあと思いつつ駄目元でJcode.pmを同じファイルに使ってみたところちゃんと判定するじゃありませんか。…???。Encode.pmのwrapperになってるはずなので、結果は同じ(判定に失敗)と思ってた。

ここはありがたくJcode.pmを使わせていただくことに。

標準入力から受け取ったら、

Jcode::convert($str,’utf8’)

と文字コードをutf8に。(互換のために参照渡しでもいいけど、参照渡しにする必要はないっぽい)多分文字コードを変える時にutf8フラグを落とすので、Jcodeで文字コードを変えたら

Encode::decode(’utf8’,文字)と、utf8フラグをつけてあげる。

もしかするとperlIOで上記の手間は不要かもしれないなぁ。


んで、urlエンコードする場合はutf8フラグを落としてやらないと、エンコードされす、日本語なんかがそのまま流れることになるので要注意。


昨日に続いて長文連載。どうせ忘れるに決まってるから、こうやってあちこちに自分メモ、だ。



こっちのページもutf8に移行するかなぁ。


プログラマのための文字コード技術入門 (WEB+DB PRESS plus)

『プログラマのための文字コード技術入門 (WEB+DB PRESS plus)』

矢野 啓介

<<2026/1>>
    123
45678910
11121314151617
18192021222324
25262728293031
検索:

【最近の20件】