Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSPredicate predicateWithFormat not evaluating format specifier

I have a (to me) curious case with NSPredicate's predicateWithFormat: method.

Using the following I log the description of two NSPredicate instances to the console:

NSNumber *myNumber = [NSNumber numberWithInt:1];

NSString *predicateFormatByHand = [NSString stringWithFormat:@"self MATCHES 'chp%@_img[0-9]+\\.png'", myNumber];
NSPredicate *firstPredicate = [NSPredicate predicateWithFormat:predicateFormatByHand];

NSLog(@"firstPredicate description: %@", firstPredicate);

NSPredicate *secondPredicate = [NSPredicate predicateWithFormat:@"self MATCHES 'chp%@_img[0-9]+\\.png'", myNumber];

NSLog(@"secondPredicate description: %@", secondPredicate);

This outputs:

 firstPredicate description: SELF MATCHES "chp1_img[0-9]+.png"
secondPredicate description: SELF MATCHES "chp%@_img[0-9]+.png"

I would expect these descriptions to be the same.

Can someone explain why they are not?

(Following this question I've played with various escape sequences for the embedded single-quotes but when doing so keep having NSPredicate complain that it cannot then parse the format string. I'd be grateful to know what's going on.)

UPDATE: one answer suggested it's an issue with using NSNumber rather than an int, so:

NSPredicate *thirdPredicate = [NSPredicate predicateWithFormat:@"self MATCHES 'chp%d_img[0-9]+\\.png'", [myNumber intValue]];

NSLog(@"thirdPredicate description: %@", thirdPredicate);   

I began with this originally, but alas the output is the same:

thirdPredicate description: SELF MATCHES "chp%d_img[0-9]+.png"

(Something means the format specifier is not evaluated.)

like image 553
Carlton Gibson Avatar asked Sep 12 '26 22:09

Carlton Gibson


1 Answers

The answer is simple: the parser used by NSPredicate assumes that anything inside the quote marks is a string literal, and does not attempt to do any substitutions on its contents. It you need to have a dynamic string value, you will have to build the string before substituting it into the predicate format string, as in your first example.

like image 94
Dave DeLong Avatar answered Sep 15 '26 00:09

Dave DeLong