NSPredicate 未按需要过滤
Posted
技术标签:
【中文标题】NSPredicate 未按需要过滤【英文标题】:NSPredicate not filtering as desired 【发布时间】:2015-07-14 19:59:17 【问题描述】:考虑以下数组:
NSArray *dataValues = @[@"Foo[0]", @"Foo[1].bar"];
以及以下正则表达式模式、谓词和预期输出:
NSString *pattern = @"Foo[0]";
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"SELF BEGINSWITH[cd] %@", pattern];
NSArray *results = [dataValues filteredArrayUsingPredicate: predicate];
NSLog(@"matches = %ld", (long)results.count);
这会按预期在控制台中打印1
。如果我们将模式更改为:
NSString *pattern = @"Foo\\[[0-9]\\]";
我希望这会在控制台中打印2
,但它会打印0
。我已经对外部方括号进行了双重转义,以允许对其进行解析,并希望找到括号内具有数字 0 到 9 的字符串以匹配此表达式。
我已经根据以下网站检查了正则表达式,它确实可以正常工作:
http://regexr.com/3bcut
我在针对 ios 8.4 iPhone 6 Plus 模拟器运行的 Xcode(6.4、6E35b)中没有警告/错误,但为什么我的正则表达式没有按预期过滤?
【问题讨论】:
【参考方案1】:你可以根据自己的需要试试这个:
NSArray *dataValues = @[@"Foo[0]", @"Foo[1].bar"];
NSString *pattern = @"Foo[*]*";
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"SELF LIKE %@", pattern];
NSArray *results = [dataValues filteredArrayUsingPredicate: predicate];
NSLog(@"matches = %ld", (long)results.count);
你可以更基本一点并使用
NSMutableArray *results = [NSMutableArray array];
for (NSString *str in dataValues)
if ([str rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]].location != NSNotFound)
if ([str hasPrefix:@"Foo["])
[results addObject:str];
NSLog(@"matches = %ld", (long)results.count);
【讨论】:
您好,感谢您的回答。我可以理解使用字符串前缀检查(等)的替代方法,但方括号内的整数需要是动态范围,例如 0-9、10-19 等,因为代码位于 for 循环内 - 但是令我沮丧的是为什么我的正则表达式不起作用!也许是一个错误?【参考方案2】:在与 Apple 提出 TSI 之后(好吧,谁会使用这些东西?)他们说我只需要使用 MATCHES
而不是 BEGINSWITH
,后者仅用于字符串匹配 - 而我正在尝试匹配一个正则表达式。
因此,我的谓词应该是:
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"SELF MATCHES[cd] %@", pattern];
【讨论】:
以上是关于NSPredicate 未按需要过滤的主要内容,如果未能解决你的问题,请参考以下文章