UTF-8 もイマイチだが…
UTF-32 が内部文字列に使えないことがわかったので、 UTF-8 を内部文字列に使用するというルールで libiconv によるエンコーディング操作と Boost.Regex による正規表現の両方を同時に試すサンプルを作成してみました。
Makefile は作ってません\(^O^)/。試してみたい人は頑張ってコンパイルしてねw
$ g++ -std=c++0x -o regex-test regex-test.cpp EncodeString.cpp -lboost_regex
まともな環境 (Linux + GCC4.5 とか) なら上記コマンドで通るはず。libiconv を (glibc に上書きする形で) インストールしている場合は -liconv
を末尾に入れる必要があるかも。そして MinGW を使う場合は更にもう一工夫必要かも (((;/^^)/
さてこのプログラム、注目して頂きたいのは、regex-test.cpp
の以下の行です。
regex reg(u8"くま|川|(お)?魚");
正規表現を定義しているのですが、一文字でしかないはずの "お"
がわざわざ丸括弧でくくってありますね。これが Perl で use utf8;
していたり、 UTF-8 で JavaScript を書いていたりしているのであれば、不要な括弧です。
しかし、 Boost.Regex を UTF-8 で使用する場合には必要です。この括弧がなければ、 "?"
は "お"
の最終オクテットにしか適用されません。なぜなら、 Boost.Regex は UTF-8 なんて知らないので、 "お"
が論理的には 1文字でしかない、なんてことは認識できないからです。
すなわち、
regex reg(u8"くま|川|お?魚");
と書いてしまうと、"お魚"
には hit しますが、 "魚"
には hit しなくなってしまうのです。
otoco では、 MML コンパイラ機能において、プログラマブルマクロを定義できる機能を提供する予定です。具体的には Lua でマクロを定義し、そのマクロを用いて生成した MML をインライン展開できるようにする、といったものです (実際の所、言語に Lua を採用すべきか JavaScript を採用すべきか、はたまた Python を採用すべきかで迷っているところではあるのですが…)。
で、 (Lua を採用する場合には) 正規表現を用いた文字列加工を行う関数を提供するつもりでいるのですが (JavaScript とかだったら不要なんですけどね、言語機能にあるし)、仮に非 ASCII な文字 (列) を hit させようとする正規表現に "?"
やら "[
…]"
やらが使われた場合、どう扱うべきなんだろう、といった辺りが悩みどころではあったりします…。
まぁなんにせよ、他に選択の余地もないので、とりあえず内部文字列は UTF-8 で実装するという方針でやっていくことにしようかと思います。前途多難じゃ… orz
2010 年 9 月 22 日 by 村山 俊之
2011 年 12 月 27 日 1:38 AM
[...] このクラスは過去の記事においても使用しておりますが、 C++11 の勉強も兼ねて (?)、内部文字に使用する物理型と文字セットをテンプレートパラメータに指定できるテンプレートクラスに書き換えています (あ、過去の記事でのソースへのリンク先が最新版になっちゃってる…直さなきゃ…)。 [...]