包含CJK字符的字符串的长度

时间:2019-03-09 16:11:49

标签: ocaml cjk unicode-string

给定包含CJK字符的字符串时,Col5在字符串中返回错误的字符数,因为它计算字节数。例如:

String.length

字符串中有两个字符,但是# String.length "第1";; - : int = 4 返回String.length(这是字符串中的字节数)。

如何获取包含CJK字符的字符串的真实长度?

2 个答案:

答案 0 :(得分:3)

如果要计算扩展的字素簇(也称为图形字符)的数量,可以使用Uuseg进行分割:

let len = Uuseg_string.fold_utf_8 `Grapheme_cluster (fun x _ -> x + 1) 0
;; len "春"
  

1

它的优点是在存在非分解字符(如韩文中的已分解jamo)时仍然很准确:

 ;; len "\u{1112}\u{1161}\u{11AB}"
  

1

这是正确的结果,因为即使使用3个unicode标量值编写,先前的字符串也应显示为

答案 1 :(得分:0)

如评论中所述,OCaml不支持任何特定编码,因此长度为字节数。

现在,假设您使用的是Utf8编码(这是混合ascii和CJK AFAIK的最简单方法),则有几种方法可以计算出该大小。

例如,使用非常轻巧的Uutf库[EDIT]作为octachron指出,这将返回标量值而不是字符的长度,您应该使用octachron的答案。

let utf8_length s = (* returns the number of unicode scalar values *)
 let decoder = Uutf.decoder ~encoding:`UTF_8 (`String s) in
 let rec loop () = match Uutf.decode decoder with | `End -> () | _ -> loop () in
 loop ();
 Uutf.decoder_count decoder