2
votes

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?

2
Please try always to copy your actual code. The first line does not compile, and enclosing %@ in quotes in the predicate string cannot have worked at all. - Martin R
Thanks corrected, the actual code is waaay more than that. I should have been more careful to not leave the quotes out tho. - Amos
I hope you did not use stringWithFormat to build the predicate ... ? - Martin R
loool i did because parts of the predicate can change depending on a few items! let me try switching one to static.... - Amos
If you post as an answer I'll accept... I'll also edit my question to include what I initially was doing. - Amos

2 Answers

3
votes

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

0
votes

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.