iPhone Цель C - Как удалить URL-адреса из строки NSString

Я ищу эффективный способ заменить URL-адреса в NSString (или NSMutableString) словом замены 'ссылка', например...

@"This is a sample with **http://bitbanter.com** within the string and heres another **http://spikyorange.co.uk** for luck"

Я хотел бы, чтобы это стало...

@"This is a sample with **'link'** within the string and heres another **'link'** for luck"

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

Другие функции, которые будут полезны, замените @"OMG" с @"Oh my God", но не когда это часть слова, т.е. @"DOOMGAME" не следует трогать

Любые предложения приветствуются.

С уважением, Роб.

2 ответа

Решение

На самом деле это было довольно забавно, и надеюсь, что решение - это то, что вы искали. Это достаточно гибко, чтобы обслуживать не только ссылки, но и другие шаблоны, где вы можете заменить слово на другое, используя определенные условия:

Я прокомментировал большую часть кода, поэтому он должен быть достаточно понятным. Если нет, не стесняйтесь оставлять комментарии, и я сделаю все возможное, чтобы помочь:

- (NSString*)replacePattern:(NSString*)pattern withReplacement:(NSString*)replacement forString:(NSString*)string usingCharacterSet:(NSCharacterSet*)characterSetOrNil
{
    // Check if a NSCharacterSet has been provided, otherwise use our "default" one
    if (!characterSetOrNil)
    characterSetOrNil = [NSCharacterSet characterSetWithCharactersInString:@" !?,()]"];

    // Create a mutable copy of the string supplied, setup all the default variables we'll need to use
    NSMutableString *mutableString = [[[NSMutableString alloc] initWithString:string] autorelease];
    NSString *beforePatternString = nil;
    NSRange outputrange = NSMakeRange(0, 0);

    // Check if the string contains the "pattern" you're looking for, otherwise simply return it.
    NSRange containsPattern = [mutableString rangeOfString:pattern];
    while (containsPattern.location != NSNotFound)
    // Found the pattern, let's run with the changes
    {
        // Firstly, we grab the full string range
        NSRange stringrange = NSMakeRange(0, [mutableString length]);
        NSScanner *scanner = [[NSScanner alloc] initWithString:mutableString];

        // Now we use NSScanner to scan UP TO the pattern provided
        [scanner scanUpToString:pattern intoString:&beforePatternString];

        // Check for nil here otherwise you will crash - you will get nil if the pattern is at the very beginning of the string
        // outputrange represents the range of the string right BEFORE your pattern
        // We need this to know where to start searching for our characterset (i.e. end of output range = beginning of our pattern)
        if (beforePatternString != nil)
            outputrange = [mutableString rangeOfString:beforePatternString];

        // Search for any of the character sets supplied to know where to stop.
        // i.e. for a URL you'd be looking at non-URL friendly characters, including spaces (this may need a bit more research for an exhaustive list)
        NSRange characterAfterPatternRange = [mutableString rangeOfCharacterFromSet:characterSetOrNil options:NSLiteralSearch range:NSMakeRange(outputrange.length, stringrange.length-outputrange.length)];

        // Check if the link is not at the very end of the string, in which case there will be no characters AFTER it so set the NSRage location to the end of the string (== it's length)
        if (characterAfterPatternRange.location == NSNotFound)
            characterAfterPatternRange.location = [mutableString length];

        // Assign the pattern's start position and length, and then replace it with the pattern
        NSInteger patternStartPosition = outputrange.length;
        NSInteger patternLength = characterAfterPatternRange.location - outputrange.length;
        [mutableString replaceCharactersInRange:NSMakeRange(patternStartPosition, patternLength) withString:replacement];
        [scanner release];

        // Reset containsPattern for new mutablestring and let the loop continue
        containsPattern = [mutableString rangeOfString:pattern];
    }
    return [[mutableString copy] autorelease];
}

И чтобы использовать ваш вопрос в качестве примера, вот как вы могли бы назвать его:

NSString *firstString = @"OMG!!!! this is the best convenience method ever, seriously! It even works with URLs like http://www.stackru.com";
NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:@" !?,()]"];
NSString *returnedFirstString = [self replacePattern:@"OMG" withReplacement:@"Oh my God" forString:firstString usingCharacterSet:characterSet];
NSString *returnedSecondString = [self replacePattern:@"http://" withReplacement:@"LINK" forString:returnedFirstString usingCharacterSet:characterSet];
NSLog (@"Original string = %@\nFirst returned string = %@\nSecond returned string = %@", firstString, returnedFirstString, returnedSecondString);

Я надеюсь, что это помогает! Ура, Рог

Начиная с iOS 4, доступно NSRegularExpression. Помимо прочего, вы можете перечислять все совпадения в строке через блок, что позволяет вам делать с ними все, что вы хотите, или же регулярное выражение выполняет некоторые виды подстановки непосредственно для вас.

Прямые подстановки строк (например, "OMG" -> "Боже мой") могут быть выполнены напрямую с помощью NSString, используя -stringByReplacingOccurencesOfString: withString: или replaceOccurferencesOfString: withString: options: range: если ваша строка изменчива.

Другие вопросы по тегам