普段Pythonを使っていると(最近はPerlもそうなのかな)、文字列というものが内部ではUnicodeになっているものだと考えてしまう。正規表現のマッチングや文字列の置換は日本語でも問題なく通る(1文字ずつUnicodeになってるから)ものという前提でプログラムを書いてしまうのだ。
PHPはそうではない。「 」(全角空白:EUCで0xA1A1)を「 」(半角空白:0x20)に置換するとしよう。PHPはCのstr系の関数と同様、バイト列の中からA1 A1という並びを検索して、それを20に置換する。ところがEUCやSJISの特性から言って、文字という区切りがないまま2バイト系と1バイト系が混在するため、たとえば「優勝 」に含まれる全角空白を半角空白に置換しようとしても、CD A5 BE A1 A1 A1→CD A5 BE 20 A1になって化け化けになってしまう。この例はEUCだがSJISでも同じである。JISのようにkanji-inとkanji-outがあるともっと悲惨なのだがそれはひとまず置いておく。プログラマが文字を前から1バイト系2バイト系と分類して数えていって、ちゃんと処理しなければならない。
Unicode嫌いな人もいるけど、EUCやJIS、SJISのコードを生のバイト列で保持し、いちいち文字区切りを考えながら処理するというのはバカバカしいと思う。そこまで苦労しても日本語にしか対応できないのかよ、というのもあるし、日本語だろうと英語だろうと、1文字は1文字だ、それを自分で数えんのかよ。文字列型があるのにバイト列と文字コードを意識しなければならない、ってのがなんかイヤだ。でもUnicodeも実は固定長じゃないらしいんだよな(弱)。
…自分でCのときにcharじゃなくてwchar_t使ってるかと言われるとそうじゃないというのもあるな(笑)。でもCには文字列型はないからバイト列でもいいだろう、と言い訳をしておく。
そうそう、PHPにはmbstringがあるけど、正規表現がドキュメントはあるけど関数が定義されてないね。やられた。コンパイル方法のせいかな? でもmbstringは有効になってるのだが…。
Pythonはたぶん、挙動からして文字列型にエンコード情報が入ってるのではないかと思う。違うコード系のものを連結するとお互いをUnicodeに変換してから連結したりすんのかな。
何言ってるのかわかんなくなってきたけど、とにかくプログラマの負担が軽減されてほしいというのは常に思っている。文字列の中身の意味の処理(文字コード以外での言語依存処理)はアプリでやるとしても、文字コードには気を使いたくない。
(追記) 2003-11-08 26:33
ついでに言えば、MySQLもPHPと同じで、テキストを単なるバイト列として扱っていますので、短い単語で検索すると、その単語が含まれていない文書までひっかかる。いちおう終端くらいは見てるかも。たぶんPythonで実装されたSQLサーバgadfly(python.jp)とかを使うとちゃんとひっかかるものはひっかかり、ひっかからないものはひっかからないのではないかな。調べてないけど。