你所拥有的是来自两个不同世界的混合数据。您通常可能会得到一个 Unicode 代码点范围以及一个 UTF-32 字符串(其中对应关系是一对一的),因此提取子字符串将是微不足道的。你有两个选择:
- 在将数据放入 NSString 之前在 UTF-32 世界中工作
- 将 Unicode 码位范围转换为 UTF-16 单位范围
我从您的问题中假设#2是您情况下最简单的选择。
正如您所说, NSString 中的字符与 Unicode 代码点不一一对应,因为 NSString 字符是 UTF-16 单元。但是,一个 Unicode 代码点恰好对应于 NSString 中的 1 或 2 个字符。通过遍历 NSString 字符并计算 Unicode 代码点,您可以相当轻松地编写自己的范围转换例程。由于有效的 BMP 字符、前导代理和跟踪代理是不相交的,因此您甚至不关心 UTF-16 数据的字节序,这使这变得更加容易。CFString 提供了一些函数来确定每个字符是什么。因此,在伪代码中,您的计数将如下所示:
for each NSString character {
if (CFStringIsSurrogateHighCharacter(character) ||
CFStringIsSurrogateLowCharacter(character))
{
Skip forward another character in the NSString
}
Increment count of Unicode code points stepped through
}