分离Unicode连字符

non*_*all 19 java unicode ascii character ligature

在大量的unicode字符中,有一些实际上代表了多个字符,比如两个'f'字符的U + FB00连字字符ff.有没有什么方法可以轻松地将这些字符转换为多个单个字符?最好是标准Java API中可用的东西,但如果需要,我可以引用外部库.

Joa*_*uer 20

U + FB00是兼容性字符.通常,Unicode不支持连字的单独代码点(如果应该使用连字并且不应该影响数据的存储方式,则认为这是布局决策).其中一些仍然存在,以允许往返转换与旧编码的兼容性,旧编码确实将连字表示为单独的实体.

幸运的是,该字符结扎代表的信息存在于Unicode数据文件和最有能力的字符串处理系统具有内置的数据.

在Java中,你需要使用NormalizerNFKC形式:

String ff ="\uFB00";
String normalized = Normalizer.normalize(ff, Form.NFKC);
System.out.println(ff + " = " + normalized);
Run Code Online (Sandbox Code Playgroud)

这将打印

? = ff

  • @nonoitall:NFKD不是灵丹妙药:有很多连字和其他概念组合形式**它根本不起作用.**例如,它无法将*ß*或*ẞ*分解为*SS*(即使那些有一个案例折叠!),也没有*Æ*到*AE*或*æ*到*ae*,也没有*Œ*到*OE*或*œ*到*oe*.将*ð*或*đ*转换为*d*或*ø*到*o*也没用.对于所有**那些东西,你需要UCA(Unicode整理算法),**不是**NFKD.NFD/NFKD也有破坏单身人士的烦人财产,如果这对你很重要的话. (5认同)
  • @tchrist:我的理解是你提到的那些分解*应该*不能完成.它们不仅仅是印刷意义上的连字,而是使用不同的真实单独字符!如果需要,ß*可以*分解为ss(例如,如果你只能存储ASCII),但它们不是**等价的.另一方面,ff Ligature只是*印刷结扎. (5认同)
  • @tchrist,您是如何在Java中应用UCA的?例如,有一个如何分解oe的示例? (2认同)

Ste*_*n C 5

您正在谈论的过程称为规范化,并在Unicode 规范化形式技术说明中指定。

Java SE 类库中有一个名为的类java.text.Normalizer,它实现了这个过程。但是,您需要阅读上面链接的 Unicode 文档,以确定需要使用哪种“规范化形式”来获得所需的结果。这并不简单......