125

How can I detect if a string contains a certain word? For example, I have a string below which reads:

@"Here is my string."

I'd like to know if I can detect a word in the string, such as "is" for example.

Cody Guldner
  • 2,888
  • 1
  • 25
  • 36
Alex
  • 1,251
  • 2
  • 8
  • 3
  • possible duplicate of [Searching NSString Cocoa?](http://stackoverflow.com/questions/2609456/searching-nsstring-cocoa) – kennytm Jul 20 '10 at 19:24
  • A cheap-and-dirty solution, if the string is assumed to contain no punctuation, is to concatenate blanks on the front and back of BOTH strings, then do `rangeOfString`. – Hot Licks Sep 13 '12 at 19:13

7 Answers7

192

Here's how I would do it:

NSString *someString = @"Here is my string";
NSRange isRange = [someString rangeOfString:@"is " options:NSCaseInsensitiveSearch];
if(isRange.location == 0) {
   //found it...
} else {
   NSRange isSpacedRange = [someString rangeOfString:@" is " options:NSCaseInsensitiveSearch];
   if(isSpacedRange.location != NSNotFound) {
      //found it...
   }
}

You can easily add this as a category onto NSString:

@interface NSString (JRStringAdditions) 

- (BOOL)containsString:(NSString *)string;
- (BOOL)containsString:(NSString *)string
               options:(NSStringCompareOptions)options;

@end

@implementation NSString (JRStringAdditions) 

- (BOOL)containsString:(NSString *)string
               options:(NSStringCompareOptions)options {
   NSRange rng = [self rangeOfString:string options:options];
   return rng.location != NSNotFound;
}

- (BOOL)containsString:(NSString *)string {
   return [self containsString:string options:0];
}

@end
Jacob Relkin
  • 161,348
  • 33
  • 346
  • 320
  • 2
    Actually you can just add space on the beginning and end of the string and " is " will match string begins with "is" – user4951 Nov 12 '12 at 07:41
  • It stuns me that these are not part of the standard class. Thanks, @Jacob! – big_m Jul 19 '13 at 19:40
  • 1
    Actually, "length" of NSRange should be tested...not "location".Here it is directly from source: "These methods return length==0 if the target string is not found. So, to check for containment: ([str rangeOfString:@"target"].length > 0). Note that the length of the range returned by these methods might be different than the length of the target string, due composed characters and such." – GtotheB Apr 22 '14 at 00:01
  • 1
    Starting from iOS 8.0, there is a new method called `containsString` exposed in NSString. – tedyyu Nov 06 '14 at 08:14
90

Use the following code to scan the word in sentence.

NSString *sentence = @"The quick brown fox";
NSString *word = @"quack";
if ([sentence rangeOfString:word].location != NSNotFound) {
    NSLog(@"Yes it does contain that word");
}
Amit Singh
  • 2,644
  • 21
  • 20
  • how can i get the locations when i use this method on an array? – judge Mar 09 '14 at 22:25
  • Depends what you are using the search for in the array. Without using comparators I think the best way is to loop through the array and check each string for the search string. NSString * searchString; for (NSString * string in array) { if ([string rangeOfString:searchString options:NSCaseInsensitiveSearch].location != NSNotFound) { // Not in string } else { // In this string } } You can then add the strings which do contain it to a new mutable array which enables you to show them if you are searching – sam_smith Nov 03 '14 at 23:58
  • ps The formatting is all correct in the code above but obviously gets mashed by being in a comment – sam_smith Nov 03 '14 at 23:58
23

In iOS8 you can now use:

BOOL containsString = [@"Here is my string." containsString:@"is"];

There's an interesting post on how to "retrofit" it to iOS7 here: http://petersteinberger.com/blog/2014/retrofitting-containsstring-on-ios-7/

siburb
  • 4,880
  • 1
  • 25
  • 34
3

I recommend using NSLinguisticTagger. We can use it to search Here is my string. His isn't a mississippi isthmus. It is?

NSLinguisticTagger *linguisticTagger = [[NSLinguisticTagger alloc] initWithTagSchemes:@[
                                        NSLinguisticTagSchemeTokenType,
                                        ]
                                                                              options:
                                        NSLinguisticTaggerOmitPunctuation |
                                        NSLinguisticTaggerOmitWhitespace |
                                        NSLinguisticTaggerOmitOther ];
[linguisticTagger setString:@"Here is my string. His isn't a mississippi isthmus. It is?"];
[linguisticTagger enumerateTagsInRange:NSMakeRange(0,
                                                   [[linguisticTagger string] length])
                                scheme:NSLinguisticTagSchemeTokenType
                               options:
 NSLinguisticTaggerOmitPunctuation |
 NSLinguisticTaggerOmitWhitespace |
 NSLinguisticTaggerOmitOther |
 NSLinguisticTaggerJoinNames
                            usingBlock:^(NSString *tag, NSRange tokenRange, NSRange sentenceRange, BOOL *stop) {
                                NSLog(@"tag: %@, tokenRange: %@, sentenceRange: %@, token: %@",
                                      tag,
                                      NSStringFromRange(tokenRange),
                                      NSStringFromRange(sentenceRange),
                                      [[linguisticTagger string] substringWithRange:tokenRange]);
                            }];

This outputs:

tag: Word, tokenRange: {0, 4}, sentenceRange: {0, 19}, token: Here
tag: Word, tokenRange: {5, 2}, sentenceRange: {0, 19}, token: is
tag: Word, tokenRange: {8, 2}, sentenceRange: {0, 19}, token: my
tag: Word, tokenRange: {11, 6}, sentenceRange: {0, 19}, token: string
tag: Word, tokenRange: {19, 3}, sentenceRange: {19, 33}, token: His
tag: Word, tokenRange: {23, 2}, sentenceRange: {19, 33}, token: is
tag: Word, tokenRange: {25, 3}, sentenceRange: {19, 33}, token: n't
tag: Word, tokenRange: {29, 1}, sentenceRange: {19, 33}, token: a
tag: Word, tokenRange: {31, 11}, sentenceRange: {19, 33}, token: mississippi
tag: Word, tokenRange: {43, 7}, sentenceRange: {19, 33}, token: isthmus
tag: Word, tokenRange: {52, 2}, sentenceRange: {52, 6}, token: It
tag: Word, tokenRange: {55, 2}, sentenceRange: {52, 6}, token: is

It ignores His mississippi and isthmus and even identifies is inside of isn't.

Heath Borders
  • 30,998
  • 16
  • 147
  • 256
3

I hope this helps you,.. add this line at .m file or create a separate class and integrate this code.

@implementation NSString (Contains)

- (BOOL) containsString: (NSString*) substring
{
NSRange range = [self rangeOfString : substring];
BOOL found = ( range.location != NSNotFound );
return found;
}    
@end
Maniganda saravanan
  • 2,188
  • 1
  • 19
  • 35
2

With iOS 8 and Swift, we can use localizedCaseInsensitiveContainsString method

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

 string.localizedCaseInsensitiveContainsString(substring) // true
Govind
  • 2,337
  • 33
  • 43
0

A complete solution would first scan for the string (without added blanks), then check if the immediately prior character is either blank or beginning of line. Similarly check if the immediately following character is either blank or end of line. If both tests pass then you have a match. Depending on your needs you might also check for ,, ., (), etc.

An alternative approach, of course, is to parse the string into words and check each word individually.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151