我的核心数据中有一个字符串,比如"0,1,2,3,4,5,6,7,8,9,10,11"
(假设为月份索引字符串)。我想使用谓词来获取该字段是否包含数字,比如字符串是否包含"0"。
我们不能使用"CONTAINS",因为"0"也存在于"10"中。我需要使用NSPredicate
来获取对象,以避免核心数据中的循环。
更新:我只想用NSPredicate
测试"0,1,2,3,4,5,6,7,8,9,10,11"是否包含"0"。
已解决
NSPredicate
的"MATCHES"运算符可用于与正则表达式进行比较:
NSString *searchTerm = @"0";
NSString *regex = [NSString stringWithFormat:@"(.*,)?%@(,.*)?", searchTerm];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"strIndex MATCHES %@", regex];
这对我来说很好。谢谢@skagedal的建议。我从包含id';s.
@bunty的答案是直接正确的,但有一个元答案。
您可能应该有一个Months实体,该实体在数据存储中包含一年中的12个月。然后,从包含该字符串的东西到Months实体之间建立一对多(有序或不取决于需要)关系。
然后,您只需按照关系(即myThing.months
)获取实体所需的月份。
对于大型数据库,使用字符串匹配谓词的获取将非常缓慢,而且确实有点反模式。
正如bunty所写,您可以使用正则表达式。如果我理解这个问题,你需要一个谓词来查找特定的数字字符串,但前提是不能直接在其他数字之前或之后。这可以通过正则表达式中被称为向后看和向前看断言来实现。更具体地说,否定向后看/向前看断言。
请查看NSPredcate使用的正则表达式的语法。要搜索数字1
,而不同时查找11
和10
,请使用正则表达式:
(?<!d)1(?!d)
因此,您可以使用以下内容构建核心数据谓词:
NSString *month = @"11"; // the number you're looking for
NSString *regex = [NSString stringWithFormat:@"(?<!d)%@(?!d)", month];
NSPredicate *myTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
这将不是一个非常有效的搜索,但如果这就是你的核心数据模型的样子,并且你不能轻易地改变它,它可能会很好地工作。如果可以的话,我会接受bbum的建议,重新组织你的模型。
您可以使用以下正则表达式检查逗号分隔的数字:
NSString *str = @"0,1,2,3,4,5,6,7,8,9,10,11";
NSString *regex = @"(\d+)(,\s*\d+)*";
NSPredicate *myTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
if ([myTest evaluateWithObject: str])
NSLog(@"matched");
else
NSLog(@"not matched");
因此,在从字段名如下的核心数据中提取数据时使用此谓词:
NSError* error = nil;
NSString *regex = @"(\d+)(,\s*\d+)*";
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"TableName" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"MonthFieldName MATCHES %@", regex];
[fetchRequest setPredicate:predicate];
NSArray* arrRecords = [context executeFetchRequest:fetchRequest error:&error];