Amos
Amos

Reputation: 182

How to escape a trailing backslash in an NSPredicate format string

I'm using Core Data and I have a predicate like this in a fetch request:

NSString *predicateStr = [NSString stringWithFormat:@"name like[c] '%@'",name];
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateStr];

This works great with one exception: sometimes it's possible that the name may end with a backslash ( "\" ) since that part is user-generated and can also come from outside the app.

When it does, I get an error like this:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'Unable to parse the format string "(name like[c] 'mqcu\')"'

So I tried using stringByReplacingOccurrencesOfString like this:

NSString *predicateStr = [NSString stringWithFormat:@"(name like[c] '%@')", [name stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"]];

but then I get an error like this:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'The backslash is a wildcard char, and cannot appear unescaped at the end of a string.'

How do I properly escape the backslash?

Upvotes: 2

Views: 1900

Answers (2)

rene
rene

Reputation: 2124

Depending on what your needs are, you may be able to build your predicate using ==, BEGINSWITH, CONTAINS, etc. instead of LIKE. Then you will not need to worry about escaping special characters.

If you use LIKE or MATCHES then you must escape special characters.

Upvotes: 0

Martin R
Martin R

Reputation: 539965

You should never use stringWithFormat to build predicates. stringWithFormat handles the %K and %@ and the quoting differently from predicateWithFormat, so combining these methods can easily fail (as in your case).

If the predicate has variable parts that are only known at runtime, you can use NSCompoundPredicate to create a complex predicate dynamically (see e.g. https://stackoverflow.com/a/13481452/1187415 for an example).

Upvotes: 3

Related Questions