分离Unicode连字字符

23

在众多的unicode字符中,有些字符实际上代表着不止一个字符,例如将两个'f'字符合成为U+FB00连字体ff。有没有一种简单的方法可以将这样的字符转换为多个单个字符?最好是Java标准API中可用的,但如果需要,我可以参考外部库。


2
我冒昧地在你的问题中添加了关键词“连字”。 :) - deceze
谢谢 - 我不确定它们叫什么。 :-) - nonoitall
1
不返回基本单元的字形? - Steve-o
3个回答

25

U+FB00 是一个兼容性字符。一般来说,Unicode 不支持单独的连字码位(认为是否应该使用连字是布局决策,不应影响数据存储)。少数这样的字符仍然存在,以便与旧的编码进行往返转换兼容,这些旧编码将连字表示为单独的实体。

幸运的是,连字所代表的字符信息已经存在于Unicode 数据文件中,并且大多数功能强大的字符串处理系统都内置了这些数据。

在 Java 中,您需要使用NormalizerNFKC 格式:

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

这将会打印:

ff = ff

10
NFKD 不能解决所有问题:有很多连字和其他组合形式是它根本无法处理的。例如,它无法将 ß 或ẞ 分解为 SS (即使这里有一个案例折叠!),也无法将 æ 分解为 AE 或ae,或将 Œ 分解为 OE 或 oe。对于将ð或đ转换为d或ø转换为o,它也毫无用处。对于所有这些事情,你需要使用UCA(Unicode Collation Algorithm)而不是NFKD。 NFD / NFKD 还具有破坏单字符的恼人特性(如果此特性对您很重要)。 - tchrist
7
我的理解是,您提到的这些分解不应该进行。它们不仅仅是在排版上意义上的连字,而是真正的独立字符,其使用方式也不同!ß 可以被分解成ss(例如如果您只能存储ASCII),但它们并不等同。另一方面,ff连字仅仅是一种排版上的连字。 - Joachim Sauer
5
@tchrist,您如何在Java中应用UCA?是否有将œ分解为oe的示例? - ledlogic

5
你所谈论的过程称为“归一化”,并在Unicode归一化形式技术说明中指定。
Java SE类库中有一个称为java.text.Normalizer的类实现了此过程。但是,您需要阅读上面链接的Unicode文件才能确定您需要使用哪种“归一化形式”以获得所需结果。这并不直观....

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接