包含CJK字符的字符串长度

问题描述 投票:2回答:2

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

# String.length "第1";;
- : int = 4

字符串中有两个字符,但String.length返回4(字符串中的字节数)。

如何获得包含CJK字符的字符串的实际长度?

ocaml cjk unicode-string
2个回答
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标量值写的。


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
© www.soinside.com 2019 - 2024. All rights reserved.