2011-03-09 57 views
1

我正在寻找一种有效的方式来取代一个NSString(或的NSMutableString)与替换单词“链接”网址中的网址,例如...iPhone目标C - 如何从一个NSString

@"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"

任何建议表示赞赏。

Regards, Rob。

+0

这不应该太难找出 - 只需搜索以“http://”开头的模式(注意http之前的空格),一旦找到,遍历字符,直到找到另一个空间,因为这将表明URL的结束。 – Rog 2011-03-09 21:17:17

回答

3

这实际上是一个有趣的玩,并希望解决方案以某种方式,你在找什么。这足够灵活,不仅适用于链接,还适用于其他模式,您可能希望使用某些条件替换另一个词:

我已经评论了大部分代码,因此它应该是非常明显的。如果没有,随时发表评论,我会尽我所能的帮助:

- (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

+0

Rog,感谢您花时间编写解决方案,我应该可以直接插入,我真的很感激!调用它的示例代码看起来像我希望的那样简单。 – 2011-03-10 07:19:28

+0

characterSetWithCharactersInString用于确定单词中的中断吗?它看起来像是用来确保OMG是开始行还是周围的其中一个分隔符? – 2011-03-10 07:20:32

+0

是的,这是正确的,所以该方法首先查找pattern =“OMG”,然后查找字符集中的任何字符(包括空格)。一旦找到,它将使用替换字符串代替“OMG”。 – Rog 2011-03-10 09:42:28

0

从iOS 4开始,可以使用NSRegularExpression。除此之外,您可以通过块枚举字符串中的所有匹配项,从而可以根据自己的需要执行任何操作,或者让正则表达式直接为您执行某些替换。

直接字符串替换(如“OMG” - >“噢,我的上帝”)可以直接通过一个NSString使用-stringByReplacingOccurencesOfString:withString:,或replaceOccurrencesOfString:withString:options:range:如果你的字符串是可变的执行。