Как отобразить персидский скрипт через юникод - PullRequest
0 голосов
/ 01 мая 2018

Кто-нибудь, пожалуйста, помогите мне отобразить эту строку в персидском сценарии: "\ u0622 \ u0662 \ u0633 \ u0627 \ u06cc \ u0645 \ u06cc \ u0644"

Я пытался использовать

NSData *data = [yourtext dataUsingEncoding:NSUTF8StringEncoding];
NSString *decodevalue = [[NSString alloc] initWithData:dataencoding:NSNonLossyASCIIStringEncoding];

и возвращается: u0622u062fu0631u0633 u0627u06ccu0645u06ccu0644

Я хочу такое же решение для цели C: https://www.codeproject.com/Questions/714169/Conversion-from-Unicode-to-Original-format-csharp

1 Ответ

0 голосов
/ 02 мая 2018

Я предполагаю, что ваша входная строка имеет коды с обратной косой чертой (как если бы это было в дословном переводе файла исходного кода), и вы хотите проанализировать 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 ...» (без косой черты), попробуйте удалить \\\\ из регулярного выражения.

Вторая часть регулярного выражения (|.) обрабатывает неэкранированные символы как есть.

Предостережения

Возможно, вы также захотите сделать регистр нечувствительным, установив правильные параметры регулярного выражения.

Это не обрабатывает недопустимые коды символов.

Это не самое эффективное решение, и вам лучше использовать подходящую библиотеку для анализа в масштабе.

Связанные документы и ссылки

...