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

我希望是这样的:

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

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

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

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


当前回答

对于iOS 8.0+和macOS 10.10+,你可以使用NSString的本地containsString:。

对于旧版本的iOS和macOS,你可以为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

注意:观察Daniel Galasko下面关于命名的评论

其他回答

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!");
}

//你也可以使用下面的语句:

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

所以我个人非常讨厌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以获得更多有用的代码。

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

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

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

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

 string.localizedCaseInsensitiveContainsString(substring) // true

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

NSString *string  = @"Hello World!";

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