我如何检查一个字符串(NSString)包含另一个较小的字符串?

我希望是这样的:

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

但我能找到的最接近的是:

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

不管怎样,这是找出字符串是否包含另一个字符串的最好方法吗?


当前回答

所以我个人非常讨厌NSNotFound,但是理解它的必要性。

但是有些人可能不理解与NSNotFound比较的复杂性

例如,下面的代码:

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

有它的问题:

1)显然,如果otherString = nil这段代码将崩溃。一个简单的测试是:

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

结果!!崩溃! !

2)对于objective-c的新手来说,不太明显的是,当string = nil时,相同的代码不会崩溃。 例如,下面的代码:

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

这段代码:

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

都会导致

does string contains string - YES

这显然不是你想要的。

所以我认为更好的解决方案是使用rangeOfString返回0的长度,然后一个更好更可靠的代码是这样的:

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

或者仅仅是:

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

对于情况1和2哪种会返回

does string contains string - NO

这是我的2美分;-)

请查看我的Gist以获得更多有用的代码。

其他回答

在iOS 8和Swift中,我们可以使用localizedCaseInsensitiveContainsString方法

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

 string.localizedCaseInsensitiveContainsString(substring) // true

在swift的情况下,可以使用这个

let string = "Package #23"
if string.containsString("Package #") {
    //String contains substring
}
else {
    //String does not contain substring
}
NSString *string = @"hello bla bla";
if ([string rangeOfString:@"bla"].location == NSNotFound) {
  NSLog(@"string does not contain bla");
} else {
  NSLog(@"string contains bla!");
}

关键是注意到rangeOfString:返回一个NSRange结构体,并且文档说如果“haystack”不包含“needle”,它返回结构体{NSNotFound, 0}。


如果你在iOS 8或OS X Yosemite上,你现在可以这样做:*(注意:如果在iOS7设备上调用此代码,这将使你的应用程序崩溃)。

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

(这也是它在Swift中的工作方式)

如果不介意区分大小写的字符串。 试试这个。

NSString *string  = @"Hello World!";

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

联机(更少的代码。DRY,因为你只有一个NSLog):

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