【问题标题】:How to replace words in a string easier in objective-c如何在objective-c中更轻松地替换字符串中的单词
【发布时间】:2014-06-13 09:24:18
【问题描述】:

所以我有一个文本字段,用户可以在其中输入任何内容。我使用以下代码为输入分配一个 NSString 值:

NSString *input = _inputTextField.text;

如果用户在输入的任何地方都有“smart”这个词,那么它将用“clever”替换它。同样,如果他们“更聪明”,它将用“更聪明”代替。我有以下代码来实现这一点:

input = [input stringByReplacingOccurrencesOfString:@"smart" withString:@"clever"];
input = [input stringByReplacingOccurrencesOfString:@"smarter" withString:@"cleverer"];

现在这很完美,但是我在运行应用程序时遇到了问题。如果用户有任何包含“smart”的词,例如“smartweed”,那么它将变成“cleverweed”,甚至不是一个词。为了绕过这个,我添加了以下代码:

input = [input stringByReplacingOccurrencesOfString:@"cleverweed" withString:@"smartweed"];

现在,我知道我不必对存在的每个包含“智能”的单词都这样做,因此我将代码更改为:

input = [input stringByReplacingOccurrencesOfString:@" smart " withString:@" clever "];

嘿,解决了。但是后来我遇到了一个问题......如果“smart”这个词是一个句子的开头,或者是一个句子的最后一个,它不会解决它!我可以通过添加以下内容来修复它:

input = [input stringByReplacingOccurrencesOfString:@"Smart " withString:@"Clever "];
input = [input stringByReplacingOccurrencesOfString:@" smart." withString:@" clever."];

以此类推,无论句子的结尾是什么。

现在,我的官方问题是,有没有一种方法可以让代码将“智能”替换为“聪明”而不改变出现在其他单词中的“智能”一词?我看过 NSRange,但我很困惑如何在这里正确使用它,因为它可能取决于用户输入的任何内容。

另外,我试过搜索这个,但找不到。

【问题讨论】:

    标签: objective-c string text replace nsstring


    【解决方案1】:

    这个问题实际上不是很清楚(标题中提到的文本字段与它有什么关系?),并且在引擎盖下它涉及自然语言处理,这是一个主题.

    无论如何,对于解决您提到的问题的直接替换,您可以使用正则表达式:

    NSString *text = @"This is a smart dog that avoids eating the smartweed";
    
    NSString *pattern = @"(?wi)\\bsmart\\b";
    
    NSString *result = [text stringByReplacingOccurrencesOfString: pattern
                                                       withString: @"clever"
                                                          options: NSRegularExpressionSearch
                                                            range: NSMakeRange(0, [text length]) ];    
    

    \b 标识正则表达式中的单词边界,括号中的 w 将使其根据 unicode(而不是传统的正则表达式规则)处理单词边界,而 i 使搜索不区分大小写。但请注意,虽然搜索不区分大小写,但替换仍然是您输入的文字字符串 - 即本示例中的小写。

    您将遇到的问题是保持大小写、处理复数等,因此最终您会想要使用更强大的框架。

    【讨论】:

    • 我的第一行代码回答了你的问题。它必须这样做,TextField 的输入,即用户键入的任何内容,都是将被替换的单词。用户可以输入一个段落,代码会搜索他输入的单词。这很完美!是的,你是对的,我会遇到大写字母。我一直在尝试使用不区分大小写的方法,并且我找到的每个解决方案,我的 xcode 总是给我一个错误,即使我复制相同的代码,我也不能使用不区分大小写。
    • @BringMe115 我对文本字段相关性的评论是指您的代码实际上只处理字符串这一事实。它们来自文本字段并不真正相关。添加了不区分大小写的搜索选项。
    • 无论哪种方式,您都给了我一个更简单的方法,让我摆脱一堆不必要的代码行。谢谢!!
    【解决方案2】:

    你必须搜索nonletter+“smart”+nonletter,其中non letter是可选的。

    在 Safari 中输入:

    NSString *string = @"smart and smartweed and smart"; // From text field
    NSString *searchWord = @"smart";
    NSString *newString = @"clever";
    NSRange wordRange;
    NSCharacterSet *letters = [NSCharacterSet letterCharacterSet];
    NSRange searchRange = NSMakeRange( 0, [string length]);
    while ((wordRange=[string rangeOfString:searchWord options:0 range:searchRange]).length!=0)
    {
      NSLog(@"%@<%@>", [string substringToIndex:searchRange.location], [string substringFromIndex:searchRange.location]);
      BOOL hasLetterAhead = YES;
      if (     (wordRange.location==0) 
           || !([letters characterIsMember:[string characterAtIndex:wordRange.location-1]]))
      {
        hasLetterAhead = NO;
      }
    
      BOOL hasLetterBehind = YES;
      if (     (wordRange.location+wordRange.length>=[string length]) 
           || !([letters characterIsMember:[string characterAtIndex:wordRange.location+wordRange.length]]))
      {
        hasLetterBehind = NO;
      }
    
      if (!hasLetterAhead && !hasLetterBehind)
      {
        string = [string stringByReplacingCharactersInRange:wordRange withString:newString];
        searchRange.location = wordRange.location + newString.length;
      }
      else
      {
        searchRange.location = wordRange.location + wordRange.length;
      }
      searchRange.length = [string length]-searchRange.location;
    }
    
    NSLog(@"%@", string);
    

    导致:

    2014-06-13 13:54:41.702 kkk[4216:303] <smart and smartweed and smart>
    2014-06-13 13:54:41.703 kkk[4216:303] clever< and smartweed and smart>
    2014-06-13 13:54:41.704 kkk[4216:303] clever and smart<weed and smart>
    2014-06-13 13:54:41.705 kkk[4216:303] clever and smartweed and clever
    

    代码搜索字符串的范围。然后它会查看它是从文本的开头开始还是前面没有字符。它在最后做同样的事情。请自行检查正确的指数计算。 :-]

    【讨论】:

    • 所以我试图让它工作,但它一直在第 14 行告诉我“预期)”,其中“{”在“letterBehind = NO;”之前;
    • 在它告诉我修复第 5 行以添加“]”后发生错误
    • 已修复。很抱歉成为坏消息的承担者,但这实际上与将“智能”替换为“聪明”完全相同,甚至在包含“智能”的单词中也是如此。如果我在句尾加上“聪明”,它实际上会冻结。
    • 不,它不在里面,而是试图一遍又一遍地替换一个不可替换的单词,而不是跳过它。推送了更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-09
    • 1970-01-01
    • 2020-05-25
    • 2010-10-14
    • 2012-09-13
    相关资源
    最近更新 更多