gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 02:00:33 25 4
gpt4 key购买 nike

读取 UTF-16 字节流的规则是什么,以确定一个字符占用多少字节?我已经阅读了这些标准,但根据对现实世界 UTF-16 编码流的经验观察,看起来有些地方标准不成立(或者我缺少标准的某个方面) .

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

<表类="s-表"><头>前导 2 个字节的值结果字符长度(字节)<正文> 0x0000-0xC7FF2 0xD800-0xDBFF4 0xDC00-0xDFFF序列无效(RFC2781 2.2.2) 0xDFFF-0xFFFF4

在实践中,这似乎是正确的,至少在某些情况下是这样。使用临时 SQL 脚本(SQL Server 2019;UTF-16 排序规则),但也使用在线解码器进行验证:

<表类="s-表"><头>字符Unicode 名称ISO 10646UTF-16编码(十六进制,大端)大小(字节)<正文>一个拉丁文大写字母 AU+0041 00 412B西里尔大写字母 BEU+0411 04 112ァ片假名字母小 AU+30A1 30 A12🐰兔子脸U+1F430 D8 3D DC 304

然而,当将以下 ISO 10646 字符编码为 UTF-16 时,它似乎是 4 个字节,但读取前导 2 个字节似乎没有迹象表明它会这么长:

<表类="s-表"><头>字符Unicode 名称UTF-16编码(十六进制,大端)大小(字节)<正文>⚕️埃斯库拉庇俄斯之杖 26 95 FE 0F4

虽然我宁愿让我的问题与软件无关;以下 SQL 将使用默认排序规则和默认语言在 Microsoft SQL Server 2019 上重现此行为。 (请注意 SQL Server 是小端)。

select cast(N'⚕️' as varbinary);
----------
0x95260FFE

很简单,你如何/为什么阅读 0x2695 并认为“我需要读入这个字符的下一个词。”?为什么这似乎与已发布的 UTF-16 标准不一致?

最佳答案

所有这些的正式定义称为“扩展字素簇”,它在 Unicode Text Segmentation report 中定义。 .正如 Joachim Sauer 指出的那样,谨慎使用 Unicode 中的“字符”一词是明智的。

代码点是“U+....”语法所指的,它试图捕捉书面语言的“单位”,例如“重音符”。但是读者会想到一个字符(例如“带有重音符的 e”)是一个“字素簇”,由一个或多个代码点组成。最终呈现在屏幕上的是一个“字形”,它既依赖于上下文又依赖于字体。

Unicode 中的字素簇实际上比这更微妙。 Unicode 试图以一种“中立”的方式来定义它们。 (在考虑语言时确实没有“中性”这样的东西,但 Unicode 确实尝试了。)例如,在斯洛伐克语中,ch、dz 和 dž 都是一个字母,但在 Unicode 中被视为两个字素簇。 (试着数一数斯洛伐克语单词中的“字母”。有些单词包含字母 dz,有些单词则包含字母 d 后跟字母 z。哦,人类书写系统。我非常爱你。)

字素簇到字形的映射也很复杂。例如,在阿拉伯语中,单个字形 لا 实际上是两个字素簇,ä(阿拉伯字母 LAM)后跟 ا(阿拉伯字母 ALEF)。如果您使用鼠标选择字形,您会看到有两个可选择的部分,如果您将它们复制并粘贴到另一个窗口,您会看到它们转换成它们的组成部分。 (为了让事情变得更复杂,Unicode 为连字定义了一个代码点,ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM: ﻻ。如果你试图选择其中的一部分,你会发现你不能。这是一个“字符”。)

您的具体情况比较特殊。变体选择器早于 Unicode,主要设计用于处理汉(中文)字符的不同变体。但是,与每个 Unicode 功能一样,它最终主要用于表情符号。 VS-16 是“emoji”的表现形式。最著名的例子是红心,即 HEAVY BLACK HEART ❤,其次是 VS-16:❤️。

同样,您的角色 U+2695 STAFF OF AESCULAPIUS 是单个代码点,默认情况下(文本样式)看起来像这样:⚕。当您添加 VS-16 时,它会以“表情符号样式”呈现:⚕️。在某些方面,它是相同的“字符”。或者是吗?取决于您使用它的目的。

表情符号样式通常稍大一些,并在其 block 中居中,有时会添加颜色。请注意在每种情况下绘制五线谱之后的句点(第二个示例中没有多余的空格;字形宽得多)。

还有其他组合系统:

  • U+0031: 1
  • U+0031 U+20e3: 1⃣ (+ COMBINING ENCLOSING KEYCAP, default text style)
  • U+0031 U+20e3 U+fe0f: 1⃣️ (+ VARIATION SELECTOR-16, emoji style)

所有这些都早于 Unicode。 Modern emoji is dramatically more complicated , 并包括几个自己的组合系统(包括两个目前仅用于标志)。

但幸运的是,对于您的实际问题,您的妻子是正确的,您通常可以使用所有标记为“组合”的尾随代码点来形成一个扩展的字素簇,这对某些人来说是一种“字符” “性格”的定义足够广泛。

关于unicode - 如何确定 UTF-16 字符的字节宽度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67244569/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com