你是从一个有趣的角度来看这个的。首先要注意的是,您正在处理两个级别的文本:一个 JSON 文档和其中的一个字符串。
简介:您无需编写代码即可对其进行解码。使用将 JSON 反序列化为对象的库,例如 Newtonsoft 的 JSON.Net。
但是,首先是 Unicode。 Unicode 是一个有一点历史的字符集。与几乎所有字符集不同的是,1)它有不止一种编码,2)它还在增长。几十年前,它有
另外:使用 U+ABCD(十六进制)格式识别代码点以供讨论。
然后 Unicode 联盟决定添加更多代码点:一直到 U+10FFFF。为此,编码至少需要 21 位。 UTF-32,32 位整数,是一个明显的解决方案,但不是很密集。因此,发明了使用可变数量代码单元的编码。 UTF-8 使用一到四个 8 位代码单元,具体取决于代码点。
但是在 1990 年代,很多语言都在采用 UCS-2。当然,文档可以随意转换,但处理 UCS-2 的代码会在没有扩展字符集的兼容编码的情况下中断。由于 U+D800 到 U+DFFF 未分配,UCS-2 可以保持不变,并且那些“代理代码点”可以用于编码新的代码点。结果是 UTF-16。每个代码点都以一个或两个 16 位代码单元编码。因此,处理 UCS-2 的程序可以自动处理 UTF-16,只要它们不需要理解它。可以认为在同一系统中编写的程序正在处理 UTF-16,尤其是对于能够理解它的库。仍然存在诸如字符串长度之类的危险,它给出了 UTF-16 代码单元的数量而不是代码点的数量,但它在其他方面效果很好。
对于 \ud83e\udd14 表示法,语言在其语法或文字字符串中使用 Unicode,这是一种接受非 Unicode 编码的源文件并仍然支持所有 Unicode 代码点的方法。在 1990 年代设计时,他们只是用十六进制编写了 UCS-2 代码单元。当然,这也扩展到了 UTF-16。这种 UTF-16 代码单元转义语法允许中间系统处理具有非 Unicode 编码的源代码文件。
现在,JSON 基于 JavaScript,而 JavaScript 的字符串是 UTF-16 代码单元的序列。因此 JSON 采用了 JavaScript 的 UTF-16 代码单元转义语法。但是,它不是很有用(除非您必须处理无法使用 UTF-8 的中间系统或将它们不理解的文件视为二进制文件)。旧的 JSON 标准要求系统之间交换的 JSON 文档使用 UTF-8、UTF-16 或 UTF-32 进行编码。新的 RFC8259 需要 UTF-8。
因此,您没有“UTF-8 文本”,而是使用 UTF-8 进行 Unicode 文本编码。文本本身是一个 JSON 文档。 JSON 文档的名称和值是 Unicode 文本,作为 UTF-16 代码单元序列,允许转义。您的文档有代码点 U+1F914,不是“?”,而是“\ud83e\udd14”。
有很多库可以将 JSON 转换为对象,因此您不需要解码 JSON 文档中的名称或值。要手动执行此操作,您将识别转义前缀并将接下来的 4 个字符作为代理项的位,extracting the data bits, then combine 它们与应遵循的配对代理项中的位。