有没有办法在iOS和/或Mac OS X上转换UTF-16代码单元和UTF-32代码单元索引?

时间:2013-02-12 00:40:51

标签: ios macos unicode

我已经获得了将属性应用于字符串的范围。挑战在于范围以UTF-32代码单位提供。

是1个UTF-32代码单元,但NSString将其视为长度2,因为它是两个UTF-16代理对字符的组合字符。

另一方面,

^ิ是2个UTF-32代码单元,NSString也将其视为长度为2。

我可以找到在非组合和组合之间进行转换的简单方法。在UTF-16和字形之间 - 但不在16到32个代码单元之间。

我认为问题与询问相同:是否有一种简单的方法可以在Mac OS X和/或iOS上检测来自其他组成字符的代理对?

1 个答案:

答案 0 :(得分:2)

NSString的抽象是UTF-16“字符”。如果你想要UTF-32,那么它就不再是Cocoa的观点了。它是一个数据缓冲区。那么,你要找的是:

NSData* utf32Data = [someString dataUsingEncoding:NSUTF32StringEncoding];
uint32_t* utf32 = (uint32_t*)[utf32Data bytes];
NSUInteger count = [utf32Data length] / sizeof(utf32[0]);

然后迭代count数组的utf32元素。


以下是NSString上未经测试的类别,用于转换范围:

@interface NSString (UTF32Range)

- (NSRange) rangeFromUTF32Range:(NSRange)range;

@end

@implementation NSString (UTF32Range)

- (NSRange) rangeFromUTF32Range:(NSRange)range
{
    NSUInteger len = self.length;
    NSUInteger i = 0;
    while (i < range.location && i < len)
    {
        unichar u = [self characterAtIndex:i];
        if (CFStringIsSurrogateHighCharacter(u))
        {
            range.location++;
            i++;
        }
        i++;
    }
    while (i < range.length && i < len)
    {
        unichar u = [self characterAtIndex:i];
        if (CFStringIsSurrogateHighCharacter(u))
        {
            range.length++;
            i++;
        }
        i++;
    }

    return range;
}

@end