3

在 Objective C 中是否可以同时在 NSString 中搜索多个不同的字符串?

例如,我想在一个很长的字符串中搜索所有出现的字符串“good”、“great”、“awesome”、“incredible”、“fantastic”和“brilliant”。

我的第一个想法是使用NSString:rangeOfString: 并循环多次(每个字符串一次),但令我震惊的是,使用更长的字符串集,这可能会变得低效且缓慢。

是否有一种内置的方法来搜索这样的多个字符串,或者我应该创建自己的方法?

编辑:结果出来了!

在找到一些时间进行基准测试后,我发现 RegEx 方法确实比循环rangeInString方法慢(慢 2 倍以上)。数字,供您欣赏,如下:

包含150,000 个单词(~1103,500 个字符)和20 个 match-words的列表,存在 5412 个匹配项

NSString:rangeInString 搜索 = 231.077ms
正则表达式搜索 = 530.113ms

4

3 回答 3

4

让我感到震惊的是,使用更长的字符串集,这可能会变得低效且缓慢。

那么,你对它进行了基准测试吗?如果不是,那你无权判断它是“低效”和“慢”。过早的优化是邪恶的。坚持使用那些漂亮而简单的 for 循环和- [NSString rangeOfString:]方法。


但是:要真正回答您的问题,避免手动循环并非不可能。如果您使用NSRegularExpressionregex 之类的good|great|awesome,那么您可以一次找到所有出现的地方。不过,使用正则表达式可能比简单的字符串搜索要慢。

于 2013-08-22T16:05:10.113 回答
1

正则表达式被如此广泛地使用,以至于实现将是高效的。具体来说,正则表达式匹配将遍历输入字符串一次

NSRegularExpression *regex = 
  [NSRegularExpression regularExpressionWithPattern: @"(good|great|...)"  
                                            options: NSRegularExpressionCaseInsensitive
                                              error: ...];
NSArray *matches = [regex matchesInString: string
                                  options: 0
                                    range: NSMakeRange(0, [string length])];

for (NSTextCheckingResult *match in matches)
  ...

这是一个测试片段:

  NSString *string = @"not good nor great";

  // as above
  for (NSTextCheckingResult *match in matches)
    NSLog (@"Match: %@", match);

产生:

2013-08-22 10:21:11.644 foo[2454:707] Match: <NSSimpleRegularExpressionCheckingResult: 0x7fc954301650>{4, 4}{<NSRegularExpression: 0x7fc9543001c0> (good|great) 0x1}
2013-08-22 10:21:11.644 foo[2454:707] Match: <NSSimpleRegularExpressionCheckingResult: 0x7fc954301540>{13, 5}{<NSRegularExpression: 0x7fc9543001c0> (good|great) 0x1}
于 2013-08-22T17:05:23.947 回答
0

是的,在内部 NSString 是 unichars 的数据块。您可以检索一个指向它的指针,然后让多个队列搜索它的一部分,但您必须确保在空白字符上进行划分,以便错过两个范围的单词部分。

于 2013-08-22T16:13:20.537 回答