NSPredicate 未按需要过滤
NSPredicate not filtering as desired
考虑以下数组:
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 的字符串以匹配此表达式。
我已经根据以下网站检查了正则表达式,它确实可以正常工作:
我在 Xcode (6.4, 6E35b) 运行 中没有 warnings/errors 反对 iOS 8.4 iPhone 6 Plus 模拟器,但为什么我的正则表达式未按预期过滤?
您可以根据自己的需要尝试一下:
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);
在向 Apple 提出 TSI 后(好吧,谁会用那些东西?)他们说我只需要使用 MATCHES
而不是 BEGINSWITH
,后者仅用于字符串匹配 - 而我正在尝试匹配正则表达式。
因此我的谓词应该是:
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"SELF MATCHES[cd] %@", pattern];
考虑以下数组:
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 的字符串以匹配此表达式。
我已经根据以下网站检查了正则表达式,它确实可以正常工作:
我在 Xcode (6.4, 6E35b) 运行 中没有 warnings/errors 反对 iOS 8.4 iPhone 6 Plus 模拟器,但为什么我的正则表达式未按预期过滤?
您可以根据自己的需要尝试一下:
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);
在向 Apple 提出 TSI 后(好吧,谁会用那些东西?)他们说我只需要使用 MATCHES
而不是 BEGINSWITH
,后者仅用于字符串匹配 - 而我正在尝试匹配正则表达式。
因此我的谓词应该是:
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"SELF MATCHES[cd] %@", pattern];