Nic*_*Ath 0 java string character-encoding
我正在处理希腊语的输入,其中元音可以有重音。
\n我注意到包含带重音的元音的单词中有一些奇怪的输入,有时带重音的相同元音似乎是两个单独的字符,而其他时候带重音的相同元音似乎是一个字符,我猜不同的字符集编码对这种行为有罪。
\n示例如下所示
\n\xce\xb5\xcc\x81 -----> 是两个单独的字符,\xce\xb5和\xcc\x81
\n\xce\xad -----> 是单个字符\xce\xad
\n我对上述行为的疑问如下:
\n目前,作为解决方案,我所做的是将任何可能的两个字符元音替换为单个字符,如下所示:
\ntext = text.replaceAll("\xce\xb1\xcc\x81", "\xce\xac")\n .replaceAll("\xce\xb5\xcc\x81", "\xce\xad")\n .replaceAll("\xce\xb7\xcc\x81", "\xce\xae")\n .replaceAll("\xce\xb9\xcc\x81", "\xce\xaf")\n .replaceAll("\xcf\x85\xcc\x81", "\xcf\x8d")\n .replaceAll("\xce\xbf\xcc\x81", "\xcf\x8c")\n .replaceAll("\xcf\x89\xcc\x81", "\xcf\x8e")\n .replaceAll("\xce\x91\xcc\x81", "\xce\x86")\n .replaceAll("\xce\x95\xcc\x81", "\xce\x88")\n .replaceAll("\xce\x97\xcc\x81", "\xce\x89")\n .replaceAll("\xce\x99\xcc\x81", "\xce\x8a")\n .replaceAll("\xce\xa5\xcc\x81", "\xce\x8e")\n .replaceAll("\xce\x9f\xcc\x81", "\xce\x8c")\n .replaceAll("\xce\xa9\xcc\x81", "\xce\x8f");\nRun Code Online (Sandbox Code Playgroud)\n但应该有更好的方法来实现这一点,我使用Java进行文本处理
\n根本原因:有时有许多不同的方法用 Unicode 表示相同的字形。通常我们转换为规范形式,但有两种规范/规范化形式(分解:NFD 和组合:NFC)。Apple 更喜欢第一种(这是 Unicode 最初的首选方式),大多数其他操作系统更喜欢第二种。每种字体都有自己的偏好(但是 shaper 库会处理它)。
您可以将文本转换为规范的组合形式 (NFC),但并非所有字形都可以转换为单个字符:重音符号和基本字符的某种组合需要两个代码点(如果有多个重音符号则需要更多代码点)。
由于 Unicode 的复杂性,同一文本有多种编码方式。您可以使用锐音符号将 \xce\xb5 编码为单个字符“GREEK SMALL LETTER EPSILON WITH TONOS”(U+03AD),或编码为“GREEK SMALL LETTER EPSILON”(U+03B5) 后跟“COMBINING ACUTE ACCENT”( U+0301)。有时,不同的人和软件确实会对这些进行不同的编码。
\n要转换为“更紧凑”的编码,您可以使用该类java.text.Normalizer和规范化形式C (NFC)。
// you can pass the entire string into this:\nNormalizer.normalize("\xce\xb5\\u0301", Normalizer.Form.NFC) // produces a string with a \\u03AD char\nRun Code Online (Sandbox Code Playgroud)\n不太紧凑的编码称为 NFD。
\n