NSPredicate does not filter at will

Consider the following array:

NSArray *dataValues = @[@"Foo[0]", @"Foo[1].bar"];

      

And the following regex pattern, predicate and expected output:

NSString *pattern = @"Foo[0]";
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"SELF BEGINSWITH[cd] %@", pattern];
NSArray *results = [dataValues filteredArrayUsingPredicate: predicate];
NSLog(@"matches = %ld", (long)results.count);

      

Will print 1

to console as expected. If we change the template to:

NSString *pattern = @"Foo\\[[0-9]\\]";

      

I expect this to print 2

to the console, but it will print 0

. I escape the outer square brackets twice so that they can be parsed and expect to find strings that have numbers between 0 and 9 in parentheses to match this expression.

I have tested the regex on the following site, which works correctly:

http://regexr.com/3bcut

I have no warnings / errors in Xcode (6.4, 6E35b) working against the iOS 8.4 iPhone 6 Plus simulator, but why is my regex not filtering as expected?

+3


source to share


2 answers


After raising TSI with Apple (well, who's using these things anyway?), They said that I just need to use MATCHES

instead BEGINSWITH

, which is only used for string matching, whereas I am trying to match a regex.

So my predicate should read:



NSPredicate *predicate = [NSPredicate predicateWithFormat: @"SELF MATCHES[cd] %@", pattern];

      

0


source


You can try this depending on your needs:

    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);

      



You can go a little more thoroughly and use

    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);

      

+1


source







All Articles