我已经获得了将属性应用于字符串的范围。挑战在于范围以UTF-32代码单位提供。
是1个UTF-32代码单元,但NSString将其视为长度2,因为它是两个UTF-16代理对字符的组合字符。
另一方面,^ิ是2个UTF-32代码单元,NSString也将其视为长度为2。
我可以找到在非组合和组合之间进行转换的简单方法。在UTF-16和字形之间 - 但不在16到32个代码单元之间。
我认为问题与询问相同:是否有一种简单的方法可以在Mac OS X和/或iOS上检测来自其他组成字符的代理对?
答案 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