Objective-C NSString символьная замена - PullRequest
0 голосов
/ 17 марта 2012

У меня есть категория NSString, над которой я работаю, чтобы выполнить замену символов, аналогичную PHP strtr. Этот метод берет строку и заменяет каждое вхождение каждого символа в fromString и заменяет его на символ в toString с тем же индексом. У меня есть рабочий метод, но он не очень эффективен, и я хотел бы сделать его более быстрым и способным обрабатывать мегабайты данных.

Редактировать (для ясности):

stringByReplacingOccurrencesOfString:withString:options:range: не будет работать. Я должен взять строку типа «ABC» и после замены «A» на «B» и «B» на «A» в конечном итоге на «BAC». Последовательные вызовы stringByReplacingOccurrencesOfString:withString:options:range: приведут к появлению строки типа «AAC», которая будет неправильной.

Предложения будут отличными, пример кода будет еще лучше!

Код:

- (NSString *)stringBySubstitutingCharactersFromString:(NSString *)fromString
                                              toString:(NSString *)toString;
{
    NSMutableString *substitutedString = [self mutableCopy];
    NSString *aCharacterString;

    NSUInteger  characterIndex
    ,           stringLength = substitutedString.length;

    for (NSUInteger i = 0; i < stringLength; ++i) {
        aCharacterString = [NSString stringWithFormat: @"%C", [substitutedString characterAtIndex:i]];
        characterIndex = [fromString rangeOfString:aCharacterString].location;

        if (characterIndex == NSNotFound) continue;

        [substitutedString replaceCharactersInRange:NSMakeRange(i, 1)
                                     withString:[NSString stringWithFormat:@"%C", [toString characterAtIndex:characterIndex]]];
    }

    return substitutedString;
}

Также этот код выполняется после каждого изменения текста в текстовом представлении. Каждый раз передается вся строка. Я знаю, что есть лучший способ сделать это, но я не знаю как. Любые предложения по этому вопросу, безусловно, будут оценены!

1 Ответ

0 голосов
/ 04 апреля 2012

Вы можете сделать такой тип подстановки строк с помощью NSRegularExpression , либо изменив изменяемую строку, либо создав новую неизменяемую строку.Он будет работать с любыми двумя заменяемыми строками (даже если они содержат более одного символа), но вам нужно будет экранировать любой символ, который что-то означает в регулярном выражении (например, \ [ ( . * ? + и т. Д.).

Шаблон находит любую из двух подстрок с необязательным «что-нибудь» между ними, а затем заменяет их на две подстроки друг с другом, сохраняя необязательную строку между ними.

// These string can be of any length
NSString *firstString = @"Axa";
NSString *secondString = @"By";   
// Escaping of characters used in regular expressions has NOT been done here     
NSString *pattern = [NSString stringWithFormat:@"(%@|%@)(.*?)(%@|%@)", firstString, secondString, firstString, secondString];

NSString *string = @"AxaByCAxaCBy";

NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
                                                                       options:NSRegularExpressionCaseInsensitive
                                                                         error:&error];
if (error) {
    // Insert error handling here...
}

NSString *modifiedString = [regex stringByReplacingMatchesInString:string
                                                           options:0
                                                             range:NSMakeRange(0, [string length])
                                                      withTemplate:@"$3$2$1"];


NSLog(@"Before:\t%@", string);           // AxaByCAxaCBy
NSLog(@"After:  \t%@", modifiedString);  // ByAxaCByCAxa
...