17

土耳其语字符 'ÇçĞğİıÖöŞşÜü' 在 utf-8 编码中未正确处理,尽管它们似乎都已定义。它们的字符码都是 65533(替换字符,可能用于错误显示),并根据所选字体显示问号或框。在某些情况下,0/null 作为字符码返回。在互联网上,有很多工具提供 utf-8 定义,但我不确定工具是否使用任何定义的(真实/国际)注册表或使用已知规则和计算动态创建定义。它们的字体定义明确,当我们手动输入代码点时显示它们没有问题。这证明它们是在 utf-8 中定义的。但另一方面,它们不在编码或转换中处理,例如 ajax 请求/响应。

所以基本问题是“我们如何定义一个字符的代码点”?该问题可以按如下方式进行调整,以防止误解。假设我们已经为“Ç”准备了这样的编码数据 -> 字符:Ç 字符名称:LATIN CAPITAL LETTER C WITH CEDILLA 十六进制代码点:00C7 十进制代码点:199 十六进制 UTF-8 字节:C387 ......我们在哪里/如何将这些信息保存为标准的 utf-8 字符?我们如何分发/公开它(准备好被其他人使用)?我们是否需要任何人/基金会(如 unicode/utf-8 联盟)的任何确认,如果它们已经注册但无法正常工作,我们如何检测/修复错误?我们可以进行自定义 utf8 配置吗?如果是怎么办?

注意:这里不需要代码片段,因为它不是误用问题。

4

1 回答 1

23

您提到的字符存在于 Unicode 中。以下是它们的十六进制字符代码以及它们是如何以 UTF-8 编码的:

      Ç     ç     Ğ     ğ     İ     ı     Ö     ö     Ş     ş     Ü     ü
Code: 00c7  00e7  011e  011f  0130  0131  00d6  00f6  015e  015f  00dc  00fc
UTF8: c3 87 c3 a7 c4 9e c4 9f c4 b0 c4 b1 c3 96 c3 b6 c5 9e c5 9f c3 9c c3 bc

这意味着,例如,如果您将字节 0xc4 0x9e 写入文件,则您已写入字符Ğ,并且任何理解 UTF-8 的软件工具都必须将其读回为Ğ

更新:要在土耳其语中正确的字母顺序和大小写转换,您必须使用理解语言环境的库,就像任何其他自然语言一样。例如在 Java 中:

Locale tr = new Locale("TR","tr");     //    Turkish locale
print("ÇçĞğİıÖöŞşÜü".toUpperCase(tr)); //    ÇÇĞĞİIÖÖŞŞÜÜ
print("ÇçĞğİıÖöŞşÜü".toLowerCase(tr)); //    ççğğiıööşşüü

注意大写的 i 变成了 İ,而小写的 i 变成了 ı。你没有说你使用哪种编程语言,但它的标准库肯定也支持语言环境。

Unicode 定义了每个字符的代码点和某些属性(例如,如果它是数字或字母,如果是大写、小写或标题大小写的字母),以及处理 Unicode 文本的某些通用算法(例如,如何混合从右到左的文本和从左到右的文本)。字母顺序和正确的大小写转换由国家标准化机构定义,例如芬兰的芬兰语言学院、西班牙的Real Academia Española,独立于 Unicode。

更新 2:

((ch&0x20)==ch)世界上大多数语言的小写测试都被打破了,不仅仅是土耳其语。您提到的将大写字母转换为小写字母的算法也是如此。此外,作为字母的测试是不正确的:在许多语言中,Z 不是字母表的最后一个字母。要正确处理文本,您必须使用由知道自己在做什么的人编写的库函数。

Unicode 应该是通用的。创建国家和语言特定的编码变体是导致我们遇到 Unicode 试图解决的混乱的原因。不幸的是,没有通用的字符排序标准。例如在英语中 a = ä < z,但在瑞典语中 a < z < ä。在德语中,Ü 在一个标准中相当于 U,在另一个标准中相当于 UE。在芬兰语中 Ü = Y。没有办法对代码点进行排序,以便在每种语言中排序都是正确的。

于 2013-02-04T23:47:37.920 回答