如何在objective-c中更容易地替换字符串中的单词

时间:2014-06-13 09:24:19

标签: objective-c string text replace nsstring

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

NSString *input = _inputTextField.text;

如果用户在输入中的任何位置都有“smart”字样,那么它将以“聪明”替换它。同样,如果他们“更聪明”,它将取代“聪明”。我有以下代码来实现这一目标:

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 "];
嘿,修好了。但后来我遇到了一个问题......如果“聪明”这个词是句子的开头,或句子的最后一个,它就无法修复它!我可以通过添加以下内容来修复它:

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

等等句子结束。

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

此外,我已经尝试搜索此内容但无法找到它。

2 个答案:

答案 0 :(得分:0)

你必须搜索nonletter +“smart”+ nonletter,其中非字母是可选的。

输入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

代码搜索字符串的范围。然后看起来,它是从文本的开头开始还是在它之前没有字符。最后它也是这样。请自行检查正确的指数计算。 : - ]

答案 1 :(得分:0)

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

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

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使搜索案例不敏感。但请注意,虽然搜索不区分大小写,但替换仍将是您输入的文字字符串 - 即本例中的小写字母。

你将遇到的问题是保持大写,处理复数等等,所以在一天结束时你会想要使用更强大的框架。