Objective c 如何转换为;“组合变音符号”;在iOS上

Objective c 如何转换为;“组合变音符号”;在iOS上,objective-c,unicode,localization,nsstring,Objective C,Unicode,Localization,Nsstring,在我的应用程序中,我有一个字符,后面跟着它们的“修饰符变音符号”(例如“oˆ”,其中“ˆ”是unicode 0x02c6),我想将其转换为完全预合成的字符(例如“ô”-unicode 0x00f4)。我尝试使用NSString方法precomposedStringWithCanonicalMapping,但在几个小时的时间里,我试图找出它不起作用的原因,我发现它只将“组合变音符号”()转换为预合成字符。好的,我需要做的就是将所有的“修饰语变调标记”转换为“组合变调标记”,然后在结果字符串上执行一

在我的应用程序中,我有一个字符,后面跟着它们的“修饰符变音符号”(例如“oˆ”,其中“ˆ”是unicode 0x02c6),我想将其转换为完全预合成的字符(例如“ô”-unicode 0x00f4)。我尝试使用NSString方法precomposedStringWithCanonicalMapping,但在几个小时的时间里,我试图找出它不起作用的原因,我发现它只将“组合变音符号”()转换为预合成字符。好的,我需要做的就是将所有的“修饰语变调标记”转换为“组合变调标记”,然后在结果字符串上执行一个precomposedStringWithCanonicalMapping,我就完成了。这确实有效,但我想知道是否有一种不那么乏味/容易出错的方法可以做到这一点?下面是我的NSString分类方法,它似乎修复了大多数字符-

- (instancetype)combineDiacritics
{
    static NSDictionary<NSNumber *, NSNumber *> *sDiacriticalSubstDict; //unichar of diacritic -> unichar of combining diacritic
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //http://www.unicode.org/charts/PDF/U0300.pdf
        sDiacriticalSubstDict = @{ @(0x02cb) : @(0x0300), @(0x00b4) : @(0x0301), @(0x02c6) : @(0x0302), @(0x02dc) : @(0x0303), @(0x02c9) : @(0x0304),   //Grave, Acute, Circumflex, Tilde, Macron
                                   @(0x00af) : @(0x0305), @(0x02d8) : @(0x0306), @(0x02d9) : @(0x0307), @(0x00a8) : @(0x0308), @(0x02c0) : @(0x0309),   //Overline, Breve, Dot above, Diaeresis
                                   @(0x00b0) : @(0x030a), @(0x02da) : @(0x030b), @(0x02c7) : @(0x030c), @(0x02c8) : @(0x030d), @(0x02bb) : @(0x0312),   //Ring above, Double Acute, Caron, Vertical line above, Cedilla above
                                   @(0x02bc) : @(0x0313), @(0x02bd) : @(0x0314), @(0x02b2) : @(0x0321), @(0x02d4) : @(0x0323), @(0x02b1) : @(0x0324),   //Comma above, Reversed comma above, Palatalized hook below, Dot below, Diaeresis below
                                   @(0x00b8) : @(0x0327), @(0x02db) : @(0x0328), @(0x02cc) : @(0x0329), @(0x02b7) : @(0x032b), @(0x02cd) : @(0x0331),   //Cedilla, Ogonek, Vert line below, Inverted double arch below, Macron below
                                   };
    });
    NSMutableString* __block buffer = [NSMutableString stringWithCapacity:self.length];
    [self enumerateSubstringsInRange:NSMakeRange(0, self.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock: ^(NSString* substring, NSRange substringRange, NSRange enclosingRange, BOOL* stop) {
                          NSString *newString = nil;
                          if (substring.length == 1)    //The diacriticals are all Unicode BMP.
                          {
                              unichar uniChar = [substring characterAtIndex:0];
                              unichar newUniChar = [sDiacriticalSubstDict[@(uniChar)] integerValue];
                              if (newUniChar != 0)
                              {
                                  NSLog(@"Unichar %04x => %04x", uniChar, newUniChar);
                                  newString = [NSString stringWithCharacters:&newUniChar length:1];
                              }
                          }
                          if (newString)
                              [buffer appendString:newString];
                          else
                              [buffer appendString:substring];
                      }];

    NSString *precomposedStr = [buffer precomposedStringWithCanonicalMapping];
    return precomposedStr;
}
-(instancetype)组合数字媒体
{
静态NSDictionary*SDIACriticalSubDict;//变音的unichar->组合变音的unichar
静态调度一次;
一次发送(一次发送)^{
//http://www.unicode.org/charts/PDF/U0300.pdf
SDIACriticalSubDict={(0x02cb):@(0x0300),@(0x00b4):@(0x0301),@(0x02c6):@(0x0302),@(0x02dc):@(0x0303),@(0x02c9):@(0x0304),//严重、急性、回旋、波浪、马克龙
@(0x00af):@(0x0305),@(0x02d8):@(0x0306),@(0x02d9):@(0x0307),@(0x00a8):@(0x0308),@(0x02c0):@(0x0309),//上划线、短划线、上点、分划
@(0x00b0):@(0x030a),@(0x02da):@(0x030b),@(0x02c7):@(0x030c),@(0x02c8):@(0x030d),@(0x02bb):@(0x0312),//上方环形,双锐角,上方卡隆,上方垂直线,上方塞迪利亚
@(0x02bc):@(0x0313),@(0x02bd):@(0x0314),@(0x02b2):@(0x0321),@(0x02d4):@(0x0323),@(0x02b1):@(0x0324),//上方逗号,上方反逗号,下方腭钩,下方圆点,下方分音符
@(0x00b8):@(0x0327),@(0x02db):@(0x0328),@(0x02cc):@(0x0329),@(0x02b7):@(0x032b),@(0x02cd):@(0x0331),//Cedilla,Ogonek,下方垂直线,下方倒双拱,下方马克龙
};
});
NSMutableString*_块缓冲区=[NSMutableString stringWithCapacity:self.length];
[自枚举子字符串范围:NSMakeRange(0,self.length)选项:NSStringEnumerationByComposedCharacterSequenceusingBlock:^(NSString*子字符串,NSRange substringRange,NSRange enclosuringRange,BOOL*停止){
NSString*newString=nil;
if(substring.length==1)//变码都是Unicode BMP。
{
unichar unichar=[子字符串字符索引:0];
unichar newUniChar=[sdiacriticalsubdict[@(unichar)]integerValue];
if(newUniChar!=0)
{
NSLog(@“Unichar%04x=>%04x”,Unichar,newUniChar);
newString=[NSString stringWithCharacters:&newUniChar长度:1];
}
}
如果(新闻字符串)
[缓冲区追加字符串:新闻字符串];
其他的
[缓冲区追加字符串:子字符串];
}];
NSString*precomposedStr=[缓冲区precomposedStringWithCanonicalMapping];
返回预复合str;
}

有人知道更内置的转换方法吗?

没有内置的转换方法,因为间隔修饰符字母块(
U+02B0
U+02FF
)中的字符不打算用作变音符号。根据Unicode标准第7.8节:

它们没有正式地组合标记(gc=Mn或gc=Mc),也没有以图形方式与它们修改的基本字母组合。他们本身就是卑鄙的人物

变音符号的间隔克隆。一些公司标准明确规定了组合变音符号的间距和非间距形式,Unicode标准在实际情况下为这些解释提供了匹配代码

如果要将它们转换为组合表单,则需要从中的交叉引用构建一个表(正如您已经在做的那样)