1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OCamlで日本語を一文字ずつ扱う

Posted at

UTF-8文字列として日本語の文を一文字ずつ処理したい。

問題

OCamlには標準ライブラリに Unicode文字を扱う Uchar モジュールはあるが string から UTF-8 文字列への変換とかはやってくれない。

Uutf というライブラリがあって UTF-8文字列を処理してくれそうだけど、APIリファレンスを見る限り string との相互変換や一文字ずつfoldするみたいな関数は用意してなさそう。

UTF-8文字を一文字ずつ処理する関数を書きました

string からの変換や foldmap などできるようにしました。

型です:

utf8.mli
type t

val fold : ('a -> Uchar.t -> 'a) -> 'a -> t -> 'a
val map : (Uchar.t -> Uchar.t) -> t -> t

val uchar_of_string : string -> Uchar.t
val string_of_uchar : Uchar.t -> string

val of_string : string -> t
val to_string : t -> string

実装はこうです:

utf8.ml
type t = string

let fold f init ustr =
  Uutf.String.fold_utf_8 (fun acc _i -> function
      | `Uchar uchar -> f acc uchar
      | `Malformed _s -> acc) init ustr

let map f ustr =
  let buf = Buffer.create (String.length ustr) in
  fold (fun buf uchar -> Uutf.Buffer.add_utf_8 buf (f uchar); buf) buf ustr
  |> Buffer.contents

let uchar_of_string s =
  let decoder = Uutf.decoder ~encoding:`UTF_8 (`String s) in
  match Uutf.decode decoder with
  | `Uchar u -> u
  | _ -> failwith "Invalid UTF-8 character"

let string_of_uchar uchar =
  let buf = Buffer.create 4 in
  Uutf.Buffer.add_utf_8 buf uchar;
  Buffer.contents buf

let of_string s = s
let to_string s = s

ライセンス

public domain です。ご自由にご利用ください。

応用

かなを一文字ずつ変換するファイナルファンタジーアルベド語変換サイトを js_of_ocaml で作りました。

albhed

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?