Câu hỏi Làm thế nào để kiểm tra xem một chuỗi có chứa một chuỗi khác trong Objective-C không?


Làm thế nào tôi có thể kiểm tra xem một chuỗi (NSString) chứa một chuỗi nhỏ hơn?

Tôi đã hy vọng cho một cái gì đó như:

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

Nhưng gần nhất tôi có thể tìm thấy là:

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

Dù sao, đó là cách tốt nhất để tìm ra nếu một chuỗi có chứa một chuỗi khác?


1143
2018-05-02 15:34


gốc


Tôi cũng muốn thấy nó được thêm vào, nhưng trong khi chờ đợi, việc thêm nó vào danh mục NSString khá dễ dàng. - isaac
Sử dụng if ([string rangeOfString:@"hello"] == 0) {...} có lỗi không khớp loại cho NSRange và int. để khắc phục điều đó, bạn nên thay đổi dòng sau: if ([string rangeOfString:@"hello"].length == 0) {...} - Neeku
iOS 8 thêm containsString: và đây là một cách tối thiểu xâm lấn để thêm hỗ trợ iOS 7 petersteinberger.com/blog/2014/… - Steve Moser
Tôi đã là nhà phát triển iOS từ đầu và tôi liên tục truy cập lại bài đăng này để dán nhanh. Tôi dường như không thể ghi nhớ điều này. Bài đăng stackoverflow được truy cập nhiều nhất trong lịch sử của tôi. - VaporwareWolf


Các câu trả lời:


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

Điều quan trọng là nhận thấy rằng rangeOfString: trả về một NSRange struct, và tài liệu nói rằng nó trả về cấu trúc {NSNotFound, 0} nếu "haystack" không chứa "kim".


Và nếu bạn đang sử dụng hệ điều hành iOS 8 hoặc OS X Yosemite, giờ đây bạn có thể thực hiện: (* LƯU Ý: S This này sẽ làm hỏng ứng dụng của bạn nếu mã này được gọi trên thiết bị iOS7).

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

 


2360
2018-05-02 16:20



Để thực hiện tìm kiếm không phân biệt dạng chữ "if ([string rangeOfString: @" bla "options: NSCaseInsensitiveSearch] .location! = NSNotFound)" - Vanja
@Dave DeLong Tôi vừa đề cập đến một Danh mục mà tôi đã tạo cho mục đích này trước khi tôi đọc bản chỉnh sửa của bạn cho câu trả lời! Vì tôi chủ yếu là một nhà phát triển c # tôi vui vì họ đã thêm một phương thức chứa vào NSSTring. - dherrin79
Tại sao trình biên dịch không nói bất cứ điều gì nếu mục tiêu triển khai của tôi là iOS7 và tôi sử dụng containsString? - Ricardo
Và để tiếp tục điểm được thực hiện bởi @Vanja: nếu bạn định sử dụng mã lối tắt [string containsString] đã được giới thiệu trong iOS 8 / Yosemite, bạn có thể sử dụng mã sau cho một chuỗi không phân biệt dạng chữ: "[stringToSearch localizedCaseInsensitiveContainsString: string ] ", và cái này nếu bạn muốn thực hiện tìm kiếm trường hợp và dấu phụ không phân biệt:" [stringToSearch localizedStandardContainsString: string] ". - Scott Kohlert
@ScottKohlert Cẩn thận, [stringToSearch localizedStandardContainsString:string] đã được giới thiệu trong iOS9. - Erzékiel


LƯU Ý: Câu trả lời này hiện đã lỗi thời

Tạo danh mục cho 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

EDIT: Quan sát bình luận của Daniel Galasko bên dưới về việc đặt tên 


155
2017-07-09 02:40



1 cho mã kết quả rõ ràng hơn và khả năng sử dụng lại. Tôi biến nó thành một lớp lót return [self rangeOfString:substring].location != NSNotFound; và đưa nó vào thư viện tái cấu trúc của tôi, es_ios_utils. github.com/peterdeweese/es_ios_utils - Peter DeWeese
Có vẻ như Apple thích ý tưởng của bạn và thêm tính năng này trong iOS 8 và OSx 10.10 (Yosemite) như @DaveDeLong được đề cập trong câu trả lời của anh ấy. +1 - Islam Q.
Quy tắc chung cho danh mục obj-c là tiền tố tên phương thức với tiền tố mô-đun 3 chữ cái của bạn. Đây là ví dụ hoàn hảo vì nó bây giờ xung đột với bản phát hành iOS 7 và 10.10 - Daniel Galasko


Vì đây có vẻ là kết quả xếp hạng cao trong Google, tôi muốn thêm điều này:

iOS 8 và OS X 10.10 thêm containsString: phương pháp để NSString. Một phiên bản cập nhật của ví dụ Dave DeLong cho các hệ thống đó:

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

47
2018-06-08 21:14





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

// Bạn cũng có thể sử dụng theo cách sau:

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

35
2018-06-27 12:40





Với iOS 8 và Nhanh, chúng ta có thể sử dụng localizedCaseInsensitiveContainsString  phương pháp

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

 string.localizedCaseInsensitiveContainsString(substring) // true

21
2018-06-25 08:53



Điều này là tốt. Không biết tại sao họ không có phương pháp này cho ios 7 - Lucas
@Lucas, bởi vì Swift ra mắt với iOS 8.0. nhưng nhanh chóng, bạn vẫn có thể hỗ trợ các thiết bị với iOS 7. - Hemang


Vì vậy, cá nhân tôi thực sự ghét NSNotFound nhưng hiểu sự cần thiết của nó.

Nhưng một số người có thể không hiểu được sự phức tạp của việc so sánh với NSNotFound

Ví dụ: mã này:

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

có vấn đề của nó:

1) Rõ ràng nếu otherString = nil mã này sẽ bị lỗi. một thử nghiệm đơn giản sẽ là:

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

kết quả trong !! TAI NẠN !!

2) Điều không rõ ràng đối với người mới đến mục tiêu-c là cùng một mã sẽ KHÔNG sụp đổ khi string = nil. Ví dụ: mã này:

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

và mã này:

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

cả hai sẽ dẫn đến

does string contains string - YES

Đó rõ ràng là KHÔNG những gì bạn muốn.

Vì vậy, giải pháp tốt hơn mà tôi tin rằng các công trình là sử dụng thực tế là rangeOfString trả về độ dài 0 để sau đó một mã tốt hơn đáng tin cậy hơn là điều này:

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

HOẶC ĐƠN GIẢN:

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

mà sẽ cho các trường hợp 1 và 2 sẽ trở lại

does string contains string - NO

Đó là 2 xu của tôi ;-)

Xin vui lòng kiểm tra của tôi Ý chính để có thêm mã hữu ích.


12
2017-08-06 06:36





Một phiên bản cải tiến của Số Pigiải pháp của, một danh mục trên NSString, không chỉ cho biết, nếu một chuỗi được tìm thấy trong một chuỗi khác, mà còn lấy một phạm vi bằng tham chiếu, là:

@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

Sử dụng nó như:

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

11
2018-01-29 23:48





Đây là đoạn mã chức năng sao chép và dán:

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

8
2017-08-29 15:07



Tôi có thể biết tại sao tôi bị bỏ phiếu không? Đó là đoạn mã hoạt động - Durai Amuthan.H


Oneliner (Số lượng mã nhỏ hơn. DRY, vì bạn chỉ có một mã NSLog):

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

6
2018-01-29 23:21





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

5
2017-07-08 10:44





thử cái này,

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

4
2017-09-02 09:48