Does a NSString contain a substring ?
Here is a little tip on how to tell if a string contains another string, using the underused data type NSRange.
NSRange gives the starting location and the length of a given value, and is often used with arrays and strings. On this occasion we will use it to find the range of a substring within another string. If the range has a location, it contains the given substring. The following code does just that.
1 2 3 4 5 6 7 8 9 | NSRange textRange; textRange =[string rangeOfString:substring]; if(textRange.location != NSNotFound) { //Does contain the substring } |
Making this a case insensitive compare is also very trivial, and can be done by lowercasing both strings
1 2 3 4 5 6 7 8 9 10 | NSRange textRange; textRange =[[string lowercaseString] rangeOfString:[substring lowercaseString]]; if(textRange.location != NSNotFound) { //Does contain the substring } |
Need more
Unfortunately, if
stringisnil, then-rangeOfString:is going to give you an undefined value, especially on iPhone. You probably want to check thatstring != nilbefore calling-rangeOfString:. Here’s more information on the problem.I’m always wary of methods that return a
struct, likeNSRange, because they are ill behaved if something isnil.A very valid point Vincent.
For the people that are new to Objective-C it is important to mention that messages sent to an object that is nil, are simply ignored. But in the example above the rest of the code will still run with NSRange being undefined.
Hi, very nice post. I have been wonder’n bout this issue,so thanks for posting
Some of us even don’t realize the importance of this information. What a pity.
crisbetewsky, pity!what pity! probably because Obj-C sucks big time. People in Apple are so stupid not to use just C/C++ instead of this messed up language obj-C. (-) (+) before function call waiting for some typos and headaches.
To say it is a bit messed up is a bit extreme
Its different, and I expect a lot of people prefer it to C/C++, myself included.
@frank, you need to chill dawg. just because you dont like (or know) something doesnt mean it sucks. different strokes for different folks.
You posted this 10 months ago and it’s still helping people. Thanks for the information.
I’ll use that code A LOT.
How would I make it into a Category and just make it a part of NSString everywhere?
Hi Susan
Something like the following (as a category on NSString):
- (BOOL)doesContainSubstring:(NSString *)substring{
//If self or substring have 0 length they cannot match
//This can have odd results with NSRange
if([self length] == 0 || [substring length] == 0)
return NO;
NSRange textRange;
textRange = [[self lowercaseString] rangeOfString:[substring lowercaseString]];
if(textRange.location != NSNotFound)
{
return YES;
}else{
return NO;
}
}
I used your function and it worked great under Debug configuration, but once on Release Configuration, fails to read NSRange .. debug console ouputs:
Unable to access variable “range”
any Idea?
…solved… had something to do with compiler optimizations in release config mode, the function works great.
THANKS for your solution. It works like magic