【问题标题】:NSPredicate case-insensitive matching on to-many relationshipNSPredicate 对多对关系的不区分大小写匹配
【发布时间】:2010-12-01 05:34:30
【问题描述】:

我正在实现一个搜索字段,用户可以在其中键入一个字符串来过滤视图中显示的项目。显示的每个对象都有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 模型中定义的属性时有效。

【问题讨论】:

    标签: objective-c cocoa core-data


    【解决方案1】:

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

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

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

    【讨论】:

    • 我知道一定有我想念的方法。奇迹般有效。谢谢!
    【解决方案2】:

    我相信答案是:

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

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

    Predicate Format String Syntax

    【讨论】:

    • 这与我在原始问题中发布的第二次尝试基本相同,只是添加了变音符号标志不同。问题是当表达式的左侧不是简单字符串时,这不起作用。
    • 对我来说,[d] 选项给了我这个错误:Terminating app due to uncaught exception 'Invalid predicate option', reason: 'NSDiacriticInsensitivePredicateOption not supported for string type'
    【解决方案3】:

    如果您试图仅捕获等号但不区分大小写,我认为这是最好的解决方案

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

    你帮了我很多。谢谢大家!!!

    就我而言,我做到了:

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

    【讨论】:

    • LIKE 是 glob (?*) 匹配运算符。这只有在您传递给%@ 的字符串是全局模式时才能正常工作,因为谓词会将其解释为一个;如果字符串不是 glob 模式,则将其传递到预期的 glob 会导致问题。如果您想要严格相等,请使用 ==。
    • 天哪!!!!!!!!!!这也有效.. == [c]。这个我没试过!什么是 glob 模式,我用谷歌搜索了它,但是......它是正则表达式吗?
    • 没有。 Glob 是您在 shell 中使用的一种模式,用于一次匹配多个文件名。
    • 小提示:对于在 Realm 中使用 NSPredicate 的用户,不支持 LIKE
    【解决方案4】:

    如果您必须匹配关键字但搜索必须区分大小写in,那么您应该使用NSPredicate(format: "keywords.name =[c] %@", self.searchString)

    LIKE 不适用于字符串文字。

    【讨论】:

      【解决方案5】:

      如果您想要不区分大小写和通配符,请使用:

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

      【讨论】:

      • NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(name like[c] '*%@*')",@"search"]; 就够了。
      猜你喜欢
      • 1970-01-01
      • 2013-06-28
      • 1970-01-01
      • 1970-01-01
      • 2017-12-12
      • 2015-01-06
      • 2016-11-05
      • 2017-11-14
      • 2012-03-15
      相关资源
      最近更新 更多