【问题标题】:Using stringByReplacingOccurrencesOfString to take into consideration "words"使用 stringByReplacingOccurrencesOfString 来考虑“单词”
【发布时间】:2014-10-15 03:44:30
【问题描述】:

我的目标是使用stringByReplacingOccurrencesOfString 将出现的单词或短语替换为替换。在字典中找到单词及其替换,例如单词或短语是键,它们的值是它们的替换:

{"is fun" : "foo",
 "funny" : "bar"}

因为stringByReplacingOccurrencesOfString 是字面意思,并且忽略了西方语言约定中的“单词”,所以我遇到了以下句子的麻烦:

“他很有趣很有趣”,

短语“很有趣”实际上是使用这种方法检测到两次:第一次是“很有趣”的一部分,第二次是“很有趣”的一部分,这会导致文字出现问题出现用于单词替换,并没有意识到它实际上是另一个单词的一部分。

我想知道是否有一种方法可以使用考虑措辞的stringByReplacingOccurrencesOfString,因此像“很有趣”这样的短语可以完整地看待,而不是也被视为“ is funny" 检测到“很有趣”。

顺便说一句,这是我在遍历字典中的所有键时用于替换的代码:

NSString *newText = [wholeSentence stringByReplacingOccurrencesOfString:wordKey withString:wordValue options:NSLiteralSearch range:[wholeSentence rangeOfString:stringByReplacingOccurrencesOfString:wordKey]];
        iteratedTranslatedText = newText;

编辑 1:使用建议的解决方案,这就是我所做的:

NSString *string = @"Harry is fun. Shilp is his fun pet dog";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\bis fun\b" options:0 error:nil];
if (regex != nil) {
    NSTextCheckingResult *firstMatch = [regex firstMatchInString:string options:0 range:NSMakeRange(0, string.length)];
    //firstMatch is returning null
    if (firstMatch) {
        NSRange resultRange = [firstMatch rangeAtIndex:0];
        NSLog(@"first match at index:%lu", (unsigned long)resultRange.location);

    }
}

但是,这会将 firstMatch 返回为 null。根据单词边界上的正则表达式tutorial,这是锚定单词或短语的方法,所以我不确定它为什么不返回任何内容。感谢您的帮助!

【问题讨论】:

  • 为此你需要涉足正则表达式 (NSRegularExpression)
  • 感谢@borrrden 的提示。你会说这里推荐的答案是建议的解决方法吗? stackoverflow.com/questions/9661690/…
  • 您最好使用NSScanner,特别是如果您有很多替代品。为每个可替换的字符串循环一次将非常耗时。使用扫描仪,您只需遍历字符串一次。参见例如stackoverflow.com/a/21100435github.com/woolsweater/NSString-WSSHTMLEntityConversion(将该代码的性能与标题中链接的 repo 进行比较,看看我在说什么)。
  • 是的,这个答案很好地说明了这一点。
  • @JoshCaswell 这是关于NSScanner 的好建议,我以前从未听说过。感谢您指出!

标签: ios regex replace nsstring


【解决方案1】:

作为您的评论,您可以在项目中使用 NSRegrlarEXPression。例如:

NSString *string = @"He is funny and is fun";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"is fun([^a-zA-Z]+|$)" options:0 error:nil];
if (regex != nil) {
    NSTextCheckingResult *firstMatch = [regex firstMatchInString:string options:0 range:NSMakeRange(0, string.length)];
    if (firstMatch) {
        NSRange resultRange = [firstMatch rangeAtIndex:0];
        NSLog(@"first match at index:%d", resultRange.location);
    }
}

结果:索引处的第一个匹配:16

【讨论】:

  • 这也将匹配“他的有趣宠物狗”等。更好的正则表达式可能是/bis fun/b
  • 感谢您的加入。@borrrden 我尝试了仅使用/bis fun/b 作为模式的建议,但使用 Pandara 提供的代码没有得到任何范围匹配。我应该使用/bis fun/b([^a-zA-Z]+|$)吗?
  • 感谢您回答@Pandara。这个解决方案非常接近 - 根据评论,is fun([^a-zA-Z]+|$) 不适用于“他的有趣宠物”之类的句子,但我尝试了 /bis fun/b firstMatch 返回零。我应该如何修改正则表达式以提高准确性?谢谢!
  • 仅供参考,根据regular-expressions.info/wordboundaries.html,我意识到“锚”字是\b,但不幸的是它仍然不起作用。
  • 天哪,我输入的是正斜杠而不是反斜杠。请注意,在 Xcode 中使用它时需要对其进行转义(即输入 \\b 而不是 \b
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-14
  • 1970-01-01
  • 2011-06-20
  • 1970-01-01
  • 2015-08-29
  • 2014-07-21
相关资源
最近更新 更多