Использование Objective C / Cocoa для unescape символов Unicode, то есть \ u1234

Некоторые сайты, на которых я получаю данные, возвращают строки UTF-8, а символы UTF-8 экранированы, то есть: \u5404\u500b\u90fd

Есть ли встроенная функция cocoa, которая может помочь в этом, или мне придется написать собственный алгоритм декодирования.

    Не существует встроенной функции для выполнения функции unescaping.

    Вы можете немного NSPropertyListSerialization с помощью NSPropertyListSerialization так как NSPropertyListSerialization «старого текста» поддерживает C escaping через \Uxxxx :

     NSString* input = @"ab\"cA\"BC\\u2345\\u0123"; // will cause trouble if you have "abc\\\\uvw" NSString* esc1 = [input stringByReplacingOccurrencesOfString:@"\\u" withString:@"\\U"]; NSString* esc2 = [esc1 stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; NSString* quoted = [[@"\"" stringByAppendingString:esc2] stringByAppendingString:@"\""]; NSData* data = [quoted dataUsingEncoding:NSUTF8StringEncoding]; NSString* unesc = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:NSPropertyListImmutable format:NULL errorDescription:NULL]; assert([unesc isKindOfClass:[NSString class]]); NSLog(@"Output = %@", unesc); 

    но помните, что это не очень эффективно. Это намного лучше, если вы напишете собственный парсер. (Кстати, вы расшифровываете строки JSON? Если да, вы можете использовать существующие синтаксические анализаторы JSON .)

    Правильно, что Cocoa не предлагает решения , но Core Foundation делает: CFStringTransform .

    CFStringTransform живет в пыльном удаленном уголке Mac OS (и iOS), и поэтому он немного знает gem. Это интерфейс Apple, совместимый с ICU . Он может выполнять настоящую магию, такую ​​как транслитерации между греческими и латинскими (или любыми известными сценариями), но также может использоваться для выполнения мирских задач, таких как unescaping strings с дерьмового сервера:

     NSString *input = @"\\u5404\\u500b\\u90fd"; NSString *convertedString = [input mutableCopy]; CFStringRef transform = CFSTR("Any-Hex/Java"); CFStringTransform((__bridge CFMutableStringRef)convertedString, NULL, transform, YES); NSLog(@"convertedString: %@", convertedString); // prints: 各個都, tada! 

    Как я уже сказал, CFStringTransform действительно мощный. Он поддерживает ряд предопределенных преобразований, таких как сопоставления событий, нормализации или преобразование имени символа юникода. Вы даже можете создавать свои собственные преобразования.

    Я понятия не имею, почему Apple не делает его доступным для Cocoa.

    Изменить 2015:

    OS X 10.11 и iOS 9 добавьте следующий метод в Foundation:

     - (nullable NSString *)stringByApplyingTransform:(NSString *)transform reverse:(BOOL)reverse; 

    Таким образом, пример сверху становится …

     NSString *input = @"\\u5404\\u500b\\u90fd"; NSString *convertedString = [input stringByApplyingTransform:@"Any-Hex/Java" reverse:YES]; NSLog(@"convertedString: %@", convertedString); 

    Спасибо @nschmidt за головы.

    Вот что я написал. Надеюсь, это поможет некоторым людям.

     + (NSString*) unescapeUnicodeString:(NSString*)string { // unescape quotes and backwards slash NSString* unescapedString = [string stringByReplacingOccurrencesOfString:@"\\\"" withString:@"\""]; unescapedString = [unescapedString stringByReplacingOccurrencesOfString:@"\\\\" withString:@"\\"]; // tokenize based on unicode escape char NSMutableString* tokenizedString = [NSMutableString string]; NSScanner* scanner = [NSScanner scannerWithString:unescapedString]; while ([scanner isAtEnd] == NO) { // read up to the first unicode marker // if a string has been scanned, it's a token // and should be appended to the tokenized string NSString* token = @""; [scanner scanUpToString:@"\\u" intoString:&token]; if (token != nil && token.length > 0) { [tokenizedString appendString:token]; continue; } // skip two characters to get past the marker // check if the range of unicode characters is // beyond the end of the string (could be malformed) // and if it is, move the scanner to the end // and skip this token NSUInteger location = [scanner scanLocation]; NSInteger extra = scanner.string.length - location - 4 - 2; if (extra < 0) { NSRange range = {location, -extra}; [tokenizedString appendString:[scanner.string substringWithRange:range]]; [scanner setScanLocation:location - extra]; continue; } // move the location pas the unicode marker // then read in the next 4 characters location += 2; NSRange range = {location, 4}; token = [scanner.string substringWithRange:range]; unichar codeValue = (unichar) strtol([token UTF8String], NULL, 16); [tokenizedString appendString:[NSString stringWithFormat:@"%C", codeValue]]; // move the scanner past the 4 characters // then keep scanning location += 4; [scanner setScanLocation:location]; } // done return tokenizedString; } + (NSString*) escapeUnicodeString:(NSString*)string { // lastly escaped quotes and back slash // note that the backslash has to be escaped before the quote // otherwise it will end up with an extra backslash NSString* escapedString = [string stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"]; escapedString = [escapedString stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; // convert to encoded unicode // do this by getting the data for the string // in UTF16 little endian (for network byte order) NSData* data = [escapedString dataUsingEncoding:NSUTF16LittleEndianStringEncoding allowLossyConversion:YES]; size_t bytesRead = 0; const char* bytes = data.bytes; NSMutableString* encodedString = [NSMutableString string]; // loop through the byte array // read two bytes at a time, if the bytes // are above a certain value they are unicode // otherwise the bytes are ASCII characters // the %C format will write the character value of bytes while (bytesRead < data.length) { uint16_t code = *((uint16_t*) &bytes[bytesRead]); if (code > 0x007E) { [encodedString appendFormat:@"\\u%04X", code]; } else { [encodedString appendFormat:@"%C", code]; } bytesRead += sizeof(uint16_t); } // done return encodedString; } 

    простой код:

     const char *cString = [unicodeStr cStringUsingEncoding:NSUTF8StringEncoding]; NSString *resultStr = [NSString stringWithCString:cString encoding:NSNonLossyASCIIStringEncoding]; 

    от: https://stackoverflow.com/a/7861345

    Давайте будем гением компьютера.