8

以下示例取自字符串和字符文档

在此处输入图像描述

55357U+D83D十六进制)和56374U+DC36十六进制)是形成 Unicode 标量的代理对U+1F436,它是DOG FACE字符。有没有办法去另一个方向?也就是说,我可以将代理对转换为标量吗?

我试过了

let myChar: Character = "\u{D83D}\u{DC36}"

但我收到“无效的 Unicode 标量”错误。

这个 Objective C 答案这个项目似乎是自定义解决方案,但是 Swift(尤其是 Swift 2.0+)中是否有任何内置的东西可以做到这一点?

4

2 回答 2

6

有一些公式可以根据代理对计算原始代码点,反之亦然。来自https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae

Unicode 标准 3.0 的第 3.7 节定义了与代理对相互转换的算法。

根据以下公式,C大于的代码点0xFFFF对应于代理对 :<H, L>

H = Math.floor((C - 0x10000) / 0x400) + 0xD800
L = (C - 0x10000) % 0x400 + 0xDC00

反向映射,即从代理对<H, L>到 Unicode 代码点C,由下式给出:

C = (H - 0xD800) * 0x400 + L - 0xDC00 + 0x10000
于 2015-07-08T08:16:49.290 回答
3

给定一个 UTF-16 代码单元序列(即 16 位数字,例如从String.utf16数字或数字数组中获取),您可以使用UTF16类型及其decode方法将其转换为UnicodeScalars,然后您可以将其转换为String.

它有点蹩脚的项目,它接受一个生成器(因为它进行有状态处理)并返回一个枚举,该枚举指示一个结果(具有相关的标量类型),或者一个错误或完成。Swift 2.0 模式匹配使它更易于使用:

let u16data: [UInt16] = [0xD83D,0xDC36]
//or let u16data = "Hello, ".utf16

var g = u16data.generate()
var s: String = ""
var utf16 = UTF16()
while case let .Result(scalar) = utf16.decode(&g) {
    print(scalar, &s)
}
print(s) // prints 
于 2015-07-08T07:04:49.133 回答