【问题标题】:iPhone Objective C - How to remove URLs from an NSStringiPhone Objective C - 如何从 NSString 中删除 URL
【发布时间】:2011-03-09 21:11:35
【问题描述】:

我正在寻找一种有效的方法来用替换词“链接”替换 NSString(或 NSMutableString)中的 URL,例如 ...

@"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" 不应该被触及。

任何建议表示赞赏。

问候, 抢。

【问题讨论】:

  • 这应该不难弄清楚 - 只需搜索以“http://”开头的模式(注意 http 之前的空格),一旦找到,遍历字符直到找到另一个空格,因为这将指示 URL 的结尾。

标签: iphone objective-c regex nsstring nsmutablestring


【解决方案1】:

这实际上玩起来很有趣,希望解决方案能以某种方式满足您的需求。这足够灵活,不仅可以满足链接的需求,还可以满足您可能希望使用特定条件将单词替换为另一个单词的其他模式:

我已经对大部分代码进行了注释,所以它应该很容易解释。如果没有,请随时发表评论,我会尽力提供帮助:

- (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.stackoverflow.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);

希望对你有帮助! 干杯, 罗格

【讨论】:

  • Rog,感谢您花时间编写一个解决方案,我应该可以直接加入,我真的很感激!调用它的示例代码看起来和我希望的一样简单。
  • characterSetWithCharactersInString 是否用于确定断词?看起来这是用来确保 OMG 是行首还是被这些分隔符之一包围?
  • 是的,这是正确的,因此该方法首先查找 pattern = "OMG",然后查找字符集中的任何字符(包括空格)。一旦找到,它将使用您的替换字符串代替“OMG”。
【解决方案2】:

从 iOS 4 开始,NSRegularExpression 可用。除此之外,您可以通过块枚举字符串中的所有匹配项,允许您对每个匹配项做任何您想做的事情,或者让正则表达式直接为您执行某种替换。

直接字符串替换(如 'OMG' -> 'Oh my God')可以直接由 NSString 执行,使用 -stringByReplacingOccurencesOfString:withString:replaceOccurrencesOfString:withString:options:range: 如果您的字符串是可变的。

【讨论】:

    猜你喜欢
    • 2014-07-08
    • 1970-01-01
    • 2014-03-31
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    • 2011-05-03
    • 2011-01-24
    相关资源
    最近更新 更多