8

这必须是重复的。但是有这么多 NSPredicate 问题,我找不到合适的。

我有一个包含compositeName字段的核心数据对象列表。像“艾米莉布朗特”这样的名字可能在那里。我想使用一个搜索列表,NSPredicate它可以让我搜索“Em”,也可以搜索“Bl”,然后让这个名字出现在获取的结果中。

这一定非常容易,但正如你猜想的那样,我没有看到它。我对带有正则表达式的 NSPredicate 的功能失调尝试如下所示:

[NSPredicate predicateWithFormat:@"compositeName MATCHES[cd] '.*(?<=^|\\s)%@.*'", query];

我对这个正则表达式的想法是:

  • 之前的任意数量的字符
  • 负后视空格或开头
  • 查询
  • 之后的任意数量的字符

但它不起作用。我没有得到任何结果。我该如何解决?

PS 如果有一个没有正则表达式的 NSPredicate 解决方案也适合我的目的。

4

1 回答 1

16

您需要在谓词字符串之外构建整个正则表达式模式字符串,然后将其传递给谓词。

此外,还有一个正则表达式构造\b来匹配单词边界,这就是您所追求的。

所以总的来说,这个片段应该为你的问题提供一个简单的解决方案:

NSString *searchString = @"Em";
NSString *regexString  = [NSString stringWithFormat:@".*\\b%@.*", searchString];

NSPredicate *pred = [NSPredicate predicateWithFormat:@"self.compositeName matches[cd] %@", regexString];

如果输入搜索文本尚未被清理,您可能希望在将其传递给正则表达式引擎之前执行此操作。

另一个改进可能是在单词边界处接受 unicode 字符,以允许人们搜索“Ántonio”、“Über”和其他类似的字符串。

以下代码行将创建一个处理这两个方面的正则表达式模式:

NSString *orgSearchString = @"^";

NSString *escapedSearchString = [NSRegularExpression escapedPatternForString: orgSearchString];

NSString *regexString  = [NSString stringWithFormat:@"(?w:).*\\b%@.*", escapedSearchString];
于 2012-06-17T15:29:47.370 回答