[ios] How do I check if a string contains another string in Objective-C?

How can I check if a string (NSString) contains another smaller string?

I was hoping for something like:

NSString *string = @"hello bla bla";
NSLog(@"%d",[string containsSubstring:@"hello"]);

But the closest I could find was:

if ([string rangeOfString:@"hello"] == 0) {
    NSLog(@"sub string doesnt exist");
} 
else {
    NSLog(@"exists");
}

Anyway, is that the best way to find if a string contains another string?

This question is related to ios objective-c string range substring

The answer is


If do not bother about case-sensitive string. Try this once.

NSString *string  = @"Hello World!";

if([string rangeOfString:@"hello" options:NSCaseInsensitiveSearch].location !=NSNotFound)
{
    NSLog(@"found");
}
else
{
    NSLog(@"not found");
}

Oneliner (Smaller amount of code. DRY, as you have only one NSLog):

NSString *string = @"hello bla bla";
NSLog(@"String %@", ([string rangeOfString:@"bla"].location == NSNotFound) ? @"not found" : @"cotains bla"); 

Please use this code

NSString *string = @"hello bla bla";
if ([string rangeOfString:@"bla"].location == NSNotFound) 
{
    NSLog(@"string does not contain bla");
} 
else 
{  
    NSLog(@"string contains bla!");
}

Try this:

Swift 4.1 , 4.2:

let stringData = "Black board"

//swift quick way and case sensitive
if stringData.contains("bla") {
    print("data contains string");
}

//case sensitive
if stringData.range(of: "bla",options: .caseInsensitive) != nil {
    print("data contains string");
}else {
    print("data does not contains string");
}

For Objective-C:

NSString *stringData = @"Black board";

//Quick way and case sensitive
if ([stringData containsString:@"bla"]) {
    NSLog(@"data contains string");
}

//Case Insensitive
if ([stringData rangeOfString:@"bla" options:NSCaseInsensitiveSearch].location != NSNotFound) {
   NSLog(@"data contains string");
}else {
   NSLog(@"data does not contain string");
}

Since this seems to be a high-ranking result in Google, I want to add this:

iOS 8 and OS X 10.10 add the containsString: method to NSString. An updated version of Dave DeLong's example for those systems:

NSString *string = @"hello bla bla";
if ([string containsString:@"bla"]) {
    NSLog(@"string contains bla!");
} else {
    NSLog(@"string does not contain bla");
}

Best solution. As simple as this! If you want to find a word or part of the string. You can use this code. In this example we are going to check if the value of word contains "acter".

NSString *word =@"find a word or character here";
if ([word containsString:@"acter"]){
    NSLog(@"It contains acter");
} else {
     NSLog (@"It does not contain acter");
}

An improved version of P i's solution, a category on NSString, that not only will tell, if a string is found within another string, but also takes a range by reference, is:

@interface NSString (Contains)
-(BOOL)containsString: (NSString*)substring
              atRange:(NSRange*)range;

-(BOOL)containsString:(NSString *)substring;
@end

@implementation NSString (Contains)

-(BOOL)containsString:(NSString *)substring
              atRange:(NSRange *)range{

    NSRange r = [self rangeOfString : substring];
    BOOL found = ( r.location != NSNotFound );
    if (range != NULL) *range = r;
    return found;
}

-(BOOL)containsString:(NSString *)substring
{
    return [self containsString:substring
                        atRange:NULL];
}

@end

Use it like:

NSString *string = @"Hello, World!";

//If you only want to ensure a string contains a certain substring
if ([string containsString:@"ello" atRange:NULL]) {
    NSLog(@"YES");
}

// Or simply
if ([string containsString:@"ello"]) {
    NSLog(@"YES");
}

//If you also want to know substring's range
NSRange range;
if ([string containsString:@"ello" atRange:&range]) {
    NSLog(@"%@", NSStringFromRange(range));
}

Use the option NSCaseInsensitiveSearch with rangeOfString:options:

NSString *me = @"toBe" ;
NSString *target = @"abcdetobe" ;
NSRange range = [target  rangeOfString: me options: NSCaseInsensitiveSearch];
NSLog(@"found: %@", (range.location != NSNotFound) ? @"Yes" : @"No");
if (range.location != NSNotFound) {
// your code
}

Output result is found:Yes

The options can be "or'ed" together and include:

NSCaseInsensitiveSearch NSLiteralSearch NSBackwardsSearch and more


In case of swift, this can be used

let string = "Package #23"
if string.containsString("Package #") {
    //String contains substring
}
else {
    //String does not contain substring
}

If certain position of the string is needed, this code comes to place in Swift 3.0:

let string = "This is my string"
let substring = "my"

let position = string.range(of: substring)?.lowerBound

First string contain or not second string,

NSString *first = @"Banana";
NSString *second = @"BananaMilk";
NSRange range = [first rangeOfString:second options:NSCaseInsensitiveSearch];

if (range.length > 0) {
    NSLog(@"Detected");
}
else {
    NSLog(@"Not detected");
}

In Swift 4:

let a = "Hello, how are you?"
a.contains("Hello")   //will return true

With iOS 8 and Swift, we can use localizedCaseInsensitiveContainsString method

 let string: NSString = "Café"
 let substring: NSString = "É"

 string.localizedCaseInsensitiveContainsString(substring) // true

NSString *categoryString = @"Holiday Event";
if([categoryString rangeOfString:@"Holiday"].location == NSNotFound)
{
    //categoryString does not contains Holiday
}
else
{
    //categoryString contains Holiday
}

If you need this once write:

NSString *stringToSearchThrough = @"-rangeOfString method finds and returns the range of the first occurrence of a given string within the receiver.";
BOOL contains = [stringToSearchThrough rangeOfString:@"occurence of a given string"].location != NSNotFound;

Swift 4 And Above

let str = "Hello iam midhun"

if str.contains("iam") {
  //contains substring
}
else {
  //doesn't contain substring
}

Objective-C

NSString *stringData = @"Hello iam midhun";

if ([stringData containsString:@"iam"]) {
    //contains substring
}
else {
    //doesn't contain substring
}

-(Bool)checkIf:(String)parentString containsSubstring:(String)checkString {
    NSRange textRange =[parentString rangeOfString:checkString];
    return textRange.location != NSNotFound // returns true if parent string contains substring else returns false
  }

Here is a copy-and-paste function snippet:

-(BOOL)Contains:(NSString *)StrSearchTerm on:(NSString *)StrText
{
    return [StrText rangeOfString:StrSearchTerm 
        options:NSCaseInsensitiveSearch].location != NSNotFound;
}

So personally I really hate NSNotFound but understand its necessity.

But some people may not understand the complexities of comparing against NSNotFound

For example, this code:

- (BOOL)doesString:(NSString*)string containString:(NSString*)otherString {
    if([string rangeOfString:otherString].location != NSNotFound)
        return YES;
    else
        return NO;
}

has its problems:

1) Obviously if otherString = nil this code will crash. a simple test would be:

NSLog(@"does string contain string - %@", [self doesString:@"hey" containString:nil] ? @"YES": @"NO");

results in !! CRASH !!

2) What is not so obvious to someone new to objective-c is that the same code will NOT crash when string = nil. For example, this code:

NSLog(@"does string contain string - %@", [self doesString:nil containString:@"hey"] ? @"YES": @"NO");

and this code:

NSLog(@"does string contain string - %@", [self doesString:nil containString:nil] ? @"YES": @"NO");

will both result in

does string contains string - YES

Which is clearly NOT what you want.

So the better solution that I believe works is to use the fact that rangeOfString returns the length of 0 so then a better more reliable code is this:

- (BOOL)doesString:(NSString*)string containString:(NSString*)otherString {
    if(otherString && [string rangeOfString:otherString].length)
        return YES;
    else
        return NO;
}

OR SIMPLY:

- (BOOL)doesString:(NSString*)string containString:(NSString*)otherString {
    return (otherString && [string rangeOfString:otherString].length);
}

which will for cases 1 and 2 will return

does string contains string - NO

That's my 2 cents ;-)

Please check out my Gist for more helpful code.


NSString *myString = @"hello bla bla";
NSRange rangeValue = [myString rangeOfString:@"hello" options:NSCaseInsensitiveSearch];

if (rangeValue.length > 0)
{
    NSLog(@"string contains hello");
} 
else 
{
    NSLog(@"string does not contain hello!");
}

//You can alternatively use following too :

if (rangeValue.location == NSNotFound) 
{
    NSLog(@"string does not contain hello");
} 
else 
{
    NSLog(@"string contains hello!");
}

For iOS 8.0+ and macOS 10.10+, you can use NSString's native containsString:.

For older versions of iOS and macOS, you can create your own (obsolete) category for NSString:

@interface NSString ( SubstringSearch )
    - (BOOL)containsString:(NSString *)substring;
@end

// - - - - 

@implementation NSString ( SubstringSearch )

- (BOOL)containsString:(NSString *)substring
{    
    NSRange range = [self rangeOfString : substring];
    BOOL found = ( range.location != NSNotFound );
    return found;
}

@end

Note: Observe Daniel Galasko's comment below regarding naming


try this,

NSString *string = @"test Data";
if ([[string lowercaseString] rangeOfString:@"data"].location == NSNotFound) 
{
    NSLog(@"string does not contain Data");
}   
else 
{
    NSLog(@"string contains data!");
}

Examples related to ios

Adding a UISegmentedControl to UITableView Crop image to specified size and picture location Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Autoresize View When SubViews are Added Warp \ bend effect on a UIView? Speech input for visually impaired users without the need to tap the screen make UITableViewCell selectable only while editing Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Examples related to objective-c

Adding a UISegmentedControl to UITableView Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Warp \ bend effect on a UIView? Use NSInteger as array index Detect if the device is iPhone X Linker Command failed with exit code 1 (use -v to see invocation), Xcode 8, Swift 3 ITSAppUsesNonExemptEncryption export compliance while internal testing? How to enable back/left swipe gesture in UINavigationController after setting leftBarButtonItem? Change status bar text color to light in iOS 9 with Objective-C

Examples related to string

How to split a string in two and store it in a field String method cannot be found in a main class method Kotlin - How to correctly concatenate a String Replacing a character from a certain index Remove quotes from String in Python Detect whether a Python string is a number or a letter How does String substring work in Swift How does String.Index work in Swift swift 3.0 Data to String? How to parse JSON string in Typescript

Examples related to range

How does String substring work in Swift Creating an Array from a Range in VBA How to create range in Swift? Why is "1000000000000000 in range(1000000000000001)" so fast in Python 3? How to find integer array size in java How does one make random number between range for arc4random_uniform()? Skip over a value in the range function in python Excel Define a range based on a cell value How can I generate a random number in a certain range? Subscript out of range error in this Excel VBA script

Examples related to substring

Go test string contains substring How does String substring work in Swift Delete the last two characters of the String Split String by delimiter position using oracle SQL How do I check if a string contains another string in Swift? Python: Find a substring in a string and returning the index of the substring bash, extract string before a colon SQL SELECT everything after a certain character Finding second occurrence of a substring in a string in Java Select query to remove non-numeric characters