2014年7月26日土曜日

[OCaml]Unicodeライブラリ ucorelibを使ってみた

Camomile http://camomile.sourceforge.net/ の作者が作成した Unicodeライブラリ ucorelibを試してみた。

シグネチャを見れば、だいたい何をしているのか分かるのだけど、
検索してもサンプルコードが見当らなかったので、書いておこう。

なお、ucorelibのシグネチャはここ

Unicode文字、文字列を操作するモジュールとして、次の2つのモジュールがある。
UCharUnicode文字を操作する。
TextUnicode文字列を操作する。

他にも便利そうなモジュールがあるが、使っていない。
詳細はシグネチャを参照。

以下はutopでの実行例である。
良く使いそうな関数だけを選択した。

UCoreLibを使えるように、utopから以下を実行済み。
#require "ucorelib" ;;
open UCoreLib ;;

UCharモジュール


of_int文字コードからucharを作成する。
code文字コードを取得する。
of_charcharからucharを作成する。
eq同じ文字か比較する。
compare文字を比較する。

文字コードからucharを作成する。
utop[30]> let u_a = UChar.of_int 0x3042 (* あ *) ;;
val u_a : uchar = <abstr>

文字コードを取得する。
utop[31]> UChar.code u_a ;;
- : int = 12354

charからucharを作成する。
utop[32]> UChar.of_char 'a' ;;
- : uchar = <abstr>

同じ文字か比較する。
utop[33]> UChar.eq u_a (UChar.of_int 0x3042) ;;
- : bool = true

文字を比較する。
utop[34]> let u_i = UChar.of_int 0x3044 (* い *) ;; 
val u_i : uchar = <abstr>
utop[35]> UChar.compare u_a (* あ *)  u_i (* い *) ;;
- : int = -2

Textモジュール


of_stringstringから文字列を作成する。
to_string文字列からstringに変換する。
length文字列の長さを取得する。
eq文字列が同じか判定する。
compare文字列を比較する。
get文字列から指定位置の文字を取得する。
append文字列を連結する。
append_char文字列に文字を連結する。
sub部分文字列を取得する。
uchar文字を文字列に変換する。
empty空文字列。
fold畳み込み処理。
iterイテレート処理。

stringから文字列を作成する。
utop[36]> let t1 = Text.of_string "あいうえお" ;;
val t1 : text = <abstr>

文字列からstringに変換する。
utop[53]> Text.to_string t1;;
- : string = "あいうえお"

文字列の長さを取得する。
utop[37]> Text.length t1 ;;
- : int = 5

文字列を比較する。
utop[42]> let t2 = Text.of_string "あいうええ" ;;
val t2 : text = <abstr>
utop[43]> Text.compare t1 (* あいうえお *) t2 (* あいうええ *) ;;
- : int = 2

文字列から指定位置の文字を取得する。
utop[46]> let uc_1_2 = Text.get t1 (* あいうえお *) 2 ;;
val uc_1_2 : uchar = <abstr>
utop[49]> printf "%02X" (UChar.code uc_1_2) ;;
3046- : unit = () ← ◆「う」

文字列を連結する。
utop[54]> Text.to_string @@ Text.append t1 t2 ;;
- : string = "あいうえおあいうええ"

文字列に文字を連結する。
utop[57]> Text.to_string @@ Text.append_char u_i (* い *) t1 ;;
- : string = "あいうえおい"

関数名は append_uchar の方が良く、また、引数の順番も、最初が text 次に uchar の方が自然だと思うが、現状は、このようになっている。

部分文字列を取得する。
utop[58]> Text.to_string @@ Text.sub t1 (* あいうえお *) 1 3;;
- : string = "いうえ"

文字を文字列に変換する。
utop[59]> Text.to_string @@ Text.of_uchar uc_1_2 (* う *) ;;
- : string = "う"

畳み込み処理。
各文字の後ろに'|'を挿入した文字列を取得する例。
utop[63]> Text.fold (fun a c -> a ^ (Text.to_string (Text.of_uchar c)) ^ "|") "" t1 (* あいうえお *) ;;
- : string = "あ|い|う|え|お|"

イテレート処理。
utop[66]> Text.iter (fun c -> (printf "%s\n" (Text.to_string (Text.of_uchar c)))) t1 (* あいうえお *) ;;
あ
い
う
え
お
- : unit = ()

OCamlが標準でUnicodeに対応してくれると良いのだけど。

参考