You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NSString Unicode转义字符串解码异常求助

解决NSString双重Unicode转义字符串的解码问题

你的问题出在输入字符串是双重转义的Unicode序列——你看到的\\u3060实际上是字符串里存储了两个独立的字符:反斜杠\和u3060,而不是单个的Unicode转义标记\u3060。你原来的解码方法只对单转义的\uXXXX有效,所以才会失败。

为什么你的原代码无效?

NSNonLossyASCIIStringEncoding的作用是解析ASCII编码中用\uXXXX表示的Unicode字符,但它要求转义序列是单个反斜杠开头的。而你的输入里是\\uXXXX,解码时会把\\当成普通的反斜杠字符,不会触发Unicode转换,自然得不到预期的日文和中文。

正确的解码方案

我们可以通过正则表达式识别所有\\uXXXX格式的双重转义序列,将其转换为对应的Unicode字符,同时处理\\n这样的转义换行符。以下是完整的实现代码:

- (NSString *)decodeUnicodeEscapedString:(NSString *)input {
    // 匹配\\u开头的四位十六进制Unicode转义序列
    NSError *error = nil;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\\\u([0-9a-fA-F]{4})" 
                                                                           options:NSRegularExpressionCaseInsensitive 
                                                                             error:&error];
    
    if (!regex) {
        NSLog(@"正则表达式创建失败: %@", error);
        return input;
    }
    
    NSMutableString *result = [input mutableCopy];
    
    // 遍历所有匹配项,替换为对应的Unicode字符
    [regex enumerateMatchesInString:input 
                            options:0 
                              range:NSMakeRange(0, input.length) 
                         usingBlock:^(NSTextCheckingResult * _Nullable match, NSMatchingFlags flags, BOOL * _Nonnull stop) {
        // 提取四位十六进制字符串
        NSString *hexStr = [input substringWithRange:[match rangeAtIndex:1]];
        unsigned int unicodeValue;
        // 将十六进制转为整数
        [[NSScanner scannerWithString:hexStr] scanHexInt:&unicodeValue];
        unichar charValue = (unichar)unicodeValue;
        // 生成对应的Unicode字符
        NSString *replacement = [NSString stringWithCharacters:&charValue length:1];
        // 替换原转义序列
        [result replaceCharactersInRange:match.range withString:replacement];
    }];
    
    // 处理转义换行符\\n为实际换行符\n
    [result replaceOccurrencesOfString:@"\\n" 
                            withString:@"\n" 
                               options:0 
                                 range:NSMakeRange(0, result.length)];
    
    return result;
}

使用示例

调用这个方法测试你的输入字符串:

NSString *str = @"\\u3060\\u3044\\u3053\\u3093\\u3001\\u5927\\u6839\\n";
NSLog(@"%@", [self decodeUnicodeEscapedString:str]);

你会得到预期的输出:

だいこん、大根

额外说明

如果服务器返回的字符串还有其他转义序列(比如\\t制表符、\\r回车符),可以在最后添加对应的替换逻辑,比如:

[result replaceOccurrencesOfString:@"\\t" withString:@"\t" options:0 range:NSMakeRange(0, result.length)];
[result replaceOccurrencesOfString:@"\\r" withString:@"\r" options:0 range:NSMakeRange(0, result.length)];

内容的提问来源于stack exchange,提问作者iphonic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:13:54