Я предполагаю, что ваша входная строка имеет коды с обратной косой чертой (как если бы это было в дословном переводе файла исходного кода), и вы хотите проанализировать escape-последовательности в строке в Юникоде, а также хотите сохранить неэкранированные символы как они есть.
Вот что я придумал:
NSError *badRegexError;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(\\\\u([a-f0-9]{4})|.)" options:0 error:&badRegexError];
if (badRegexError) {
NSLog(@"bad regex: %@", badRegexError);
return;
}
NSString *input = @"\\u0622\\u062f\\u0631\\u0633 123 test -_- \\u0627\\u06cc\\u0645\\u06cc\\u0644";
NSMutableString *output = [NSMutableString new];
[regex enumerateMatchesInString:input options:0 range:NSMakeRange(0, input.length)
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
{
NSRange codeRange = [result rangeAtIndex:2];
if (codeRange.location != NSNotFound) {
NSString *codeStr = [input substringWithRange:codeRange];
NSScanner *scanner = [NSScanner scannerWithString:codeStr];
unsigned int code;
if ([scanner scanHexInt:&code]) {
unichar c = (unichar)code;
[output appendString:[NSString stringWithCharacters:&c length:1]];
}
} else {
[output appendString:[input substringWithRange:result.range]];
}
}];
NSLog(@" actual: %@", output);
NSLog(@"expected: %@", @"\u0622\u062f\u0631\u0633 123 test -_- \u0627\u06cc\u0645\u06cc\u0644");
Объяснение
Используется регулярное выражение, которое находит блоки из 6 символов, например \uXXXX
, например \u062f
. Он извлекает код в виде строки типа 062f
, а затем использует NSScanner.scanHexInt для преобразования его в число. Предполагается, что это число является действительным unichar
, и строит из него строку.
Примечание \\\\
в регулярном выражении, потому что сначала у компилятора objc один слой слешей, и он становится \\
, а затем компилятор регулярных выражений удаляет 2-й слой слешей и становится \
, который используется для точного соответствия. Если у вас просто «u0622u062f ...» (без косой черты), попробуйте удалить \\\\
из регулярного выражения.
Вторая часть регулярного выражения (|.
) обрабатывает неэкранированные символы как есть.
Предостережения
Возможно, вы также захотите сделать регистр нечувствительным, установив правильные параметры регулярного выражения.
Это не обрабатывает недопустимые коды символов.
Это не самое эффективное решение, и вам лучше использовать подходящую библиотеку для анализа в масштабе.
Связанные документы и ссылки