NSPredicate对多关系的不区分大小写匹配


68

我正在实现一个搜索字段,用户可以在其中输入字符串以过滤视图中显示的项目。每个显示的对象都有keywords一对多的关系,我希望能够根据其关键字过滤对象。每个关键字对象都有一个name属性,因此我设置了一个NSPredicate来进行如下所示的过滤:

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"keywords.name CONTAINS %@", self.searchString];

此方法有效,但问题是搜索区分大小写,因此,如果关键字具有大写字母,但用户键入的全部为小写字母,则不会找到匹配项。我尝试了以下修改:

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"keywords.name CONTAINS[c] %@", self.searchString];

但这对匹配的大小写没有影响。有没有一种方法可以仅使用普通谓词来进行不区分大小写的匹配?还是我需要在关键字类上实现某种自定义访问器,例如编写一个lowercaseName方法并与小写版本的搜索字符串进行匹配?

附录:经过进一步探索,添加自定义访问器的解决方法可以手动使用NSPredicate正常,但是在将NSFetchRequest与Core Data一起使用时根本不起作用,仅当查询Core Data模型中定义的属性时才有效。

Answers:


91

如果我理解正确,那么只要任何关键字名称与搜索字符串匹配,您都希望谓词为true。为此,您需要使用ANY关键字进行测试,如下所示:

[NSPredicate predicateWithFormat:@"ANY keywords.name CONTAINS[c] %@", ...];

这将搜索关键字,如果其中任何一个关键字名称包含您的搜索字符串,则返回true。


1
我知道一定有一种我想念的方式。奇迹般有效。谢谢!
布赖恩·韦伯斯特

50

我相信答案是:

[NSPredicate predicateWithFormat:@"keywords.name CONTAINS[cd] %@", self.searchString];

默认情况下,字符串比较是区分大小写的,并且区分变音符号。您可以使用方括号内的键字符c和d来修改运算符,以分别指定大小写和变音符号不敏感,例如firstName BEGINSWITH [cd] $ FIRST_NAME。

谓词格式字符串语法


这与我在原始问题中发布的第二次尝试基本相同,只是添加了变音符号不同。问题是,当表达式的左侧不是简单字符串时,这将不起作用。
布赖恩·韦伯斯特

1
对我来说,[d]选项给了我这个错误:Terminating app due to uncaught exception 'Invalid predicate option', reason: 'NSDiacriticInsensitivePredicateOption not supported for string type'
Zeb 2015年

13

如果您尝试仅捕获等号但不区分大小写,那么我认为这是最佳解决方案

[NSPredicate predicateWithFormat:@"ANY keywords.name LIKE[c] %@", ...];

你帮了我很多忙 多谢你们!!!

就我而言:

[NSPredicate predicateWithFormat:@"ANY name LIKE[c] %@", @"teste"];

LIKE是glob(?*)匹配运算符。仅当您传递的字符串%@是glob模式时,此方法才能正确运行,因为谓词会将其解释为一个;如果该字符串不是glob模式,则将其传递到预期的glob位置将导致问题。如果要严格相等,请使用==。
Peter Hosey

8
天啊!!!!!!!!!!这也有效.. == [c]。我还没有尝试过!什么是glob patthern,我用Google搜索了它,但是...它是正则表达式吗?
沃尔玛

不。globs是您在Shell中使用的一种模式,用于一次匹配多个文件名。
Peter Hosey 2010年

3
小提示:LIKE不支持将NSPredicate与Realm一起使用。
Zeb 2015年

6

如果必须与关键字匹配,但搜索必须病例敏感,那么你应该使用NSPredicate(format: "keywords.name =[c] %@", self.searchString)

LIKE 不适用于字符串文字。


1

如果您既希望区分大小写又要使用通配符,请使用以下命令:

NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"(name like[c] '*%@*')",@"search"]];

1
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(name like[c] '*%@*')",@"search"];足够的。
Zeb
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.