如何确定UTF-16字符的字节宽度



读取UTF-16字节流以确定一个字符占用多少字节的规则是什么?我读过这些标准,但根据对真实世界UTF-16编码流的经验观察,似乎有些地方的标准不成立(或者我遗漏了标准的某个方面)。

从阅读UTF-16标准https://www.rfc-editor.org/rfc/rfc2781:

前导2字节的值 结果字符长度(字节)
0x0000-0xC7FF 2
0xD800-0xDBFF 4
0xDC00-0xDFFF 无效序列(RFC2781 2.2.2)
0xDFFF-0xFFFF 4

所有这些的形式定义称为";扩展的字形簇;它在Unicode文本分割报告中进行了定义。正如约阿希姆·绍尔所指出的,谨慎使用";字符";在Unicode中。

代码点是什么";U+"语法是指并试图捕获";单位";书面语言,例如";尖锐的口音"但读者对一个字符(例如"带尖锐口音的e")的看法是"a";字形簇";并且由一个或多个代码点组成。最终呈现在屏幕上的是";字形";这既依赖于上下文又依赖于字体。

Unicode中的字形簇实际上比这更微妙。Unicode试图将它们定义为";"中性";方法(在考虑语言时,确实没有"中性"这回事,但Unicode确实尝试过。)例如,在斯洛伐克语中,ch、dz和dž都是一个字母,但在Unicode中被视为两个字形簇。(试着数一个斯洛伐克单词中的"字母"。有些单词包含字母dz,其他单词的字母d后面跟着字母z。哦,人类的书写系统。我太爱你了。)

字形簇到字形的映射也很复杂。例如,在阿拉伯语中,单一的字形是两个字形簇,一个是字母(阿拉伯语字母LAM),另一个是ا(阿拉伯语字母ALEF)。如果您使用鼠标选择图示符,您将看到有两个可选择的部分,如果您将它们复制并粘贴到另一个窗口,则会看到它们转换为其组成部分。(为了使事情变得更加复杂,Unicode为ligature定义了一个单独的代码点,ARABIC ligature LAM WITH ALEF ISOLATED FORM:ﻻ.如果你试着选择其中的一部分,你会发现你做不到。这是一个";性格")

你的具体情况有点特殊。变体选择器早于Unicode,主要用于处理汉(中文)字符的不同变体。然而,与所有Unicode功能一样,它最终主要用于表情符号。VS-16是";表情符号;演示形式。最著名的例子是红心,它是沉重的黑心❤,接着是VS-16:❤️.

类似地,您的角色U+2695 AESCULAPIUS STAFF是一个代码点,默认情况下(文本样式)如下:⚕.当您添加VS-16时,它以";表情符号风格":⚕️.在某些方面;性格"还是这样?这取决于你用它做什么。

表情符号风格通常稍大一点,以其块为中心,有时会添加颜色。请注意,在每种情况下,五线谱后面的句点都画在哪里(第二个例子中没有额外的空格;字形只是宽得多)。

还有其他组合系统:

  • U+0031:1
  • U+0031 U+20e3:1⃣(+组合封装KEYCAP,默认文本样式)
  • U+0031 U+20e3 U+fe0f:1⃣️(+变体选择器-16,表情符号风格)

所有这些都早于Unicode。现代表情符号要复杂得多,包括几个自己的组合系统(包括两个目前仅用于标志的组合系统)。

但幸运的是,对于你的实际问题,你的妻子是正确的,你通常可以消耗所有标记为";组合";以形成扩展的字形簇;字符";对于";性格">

您的所有断言都是完全正确的;您对UTF-16标准的解释是正确和完整的。

然而,在你的经验观察中,你假设你只有一个性格。实际上,您已经遇到了Unicode实现的细微差别。您的";字符";实际上是两个(尽管在技术上不是视觉上):U+2695〃;AESCULAPIUS的工作人员之后是U+FE0F";变异选择器-16">。第二个字符是非空格标记,它与基字符组合用于呈现字符变体。

这会产生字节序列26 95 FE 0F,但正如您所注意到的,这两个字都不在UTF-16保留扩展字符范围内。但这是因为两者都不需要UTF-16 4字节扩展名。它们被简单地分类为两个离散的Unicode字符。

来自ISO 10646:通用编码字符集(UCS)中的7.9组合标记:,

组合标记是Unicode标准中的一类特殊字符用于与前面的一个字符组合,称为它们的基。

组合标记通常具有可见的字形形式…组合标记可能以各种方式与相邻字符进行图形交互。

http://unicode.org/L2/L2010/10038-fcd10646-main.pdf


解释我为什么要回答自己的问题;我把我的SO问题都准备好了。我妻子走进我的办公室;她回头看了我一眼,对着我的耳朵轻声说:";你知道组合字符是一种东西,对吧&";。然而,我仍然问了这个问题,并亲自回答,以防我妻子的甜言蜜语帮助了社区的另一位成员

最新更新