给定包含CJK字符的字符串时,Col5
在字符串中返回错误的字符数,因为它计算字节数。例如:
String.length
字符串中有两个字符,但是# String.length "第1";;
- : int = 4
返回String.length
(这是字符串中的字节数)。
如何获取包含CJK字符的字符串的真实长度?
答案 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