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


1212

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

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, đó có phải là cách tốt nhất để tìm nếu một chuỗi chứa một chuỗi khác?


1
Tôi cũng muốn thấy nó được thêm vào, nhưng trong khi đó, việc thêm nó dưới dạng một danh mục trên NSString tương đối dễ dàng.
isaac

2
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 thành như sau:if ([string rangeOfString:@"hello"].length == 0) {...}
Neeku

1
iOS 8 thêm chứaString
Steve Moser

2
Tôi đã là một nhà phát triển iOS từ đầu và tôi liên tục xem lại bài đăng này để sao chép nhanh. Tôi dường như không thể ghi nhớ điều này. Bài viết stackoverflow truy cập nhiều nhất trong lịch sử của tôi.
VaporwareWolf

chỉ cần sử dụng Swift;)
Fattie

Câu trả lời:


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

Khóa này nhận thấy rằng rangeOfString:trả về một NSRangecấu trúc 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 dùng iOS 8 hoặc OS X Yosemite, giờ đây bạn có thể thực hiện: (* LƯU Ý: Điều này S crash 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");
}

(Đây cũng là cách nó sẽ hoạt động trong Swift)

👍


286
Để thực hiện tìm kiếm không phân biệt chữ hoa chữ thường, hãy sử dụng tùy chọn "if ([chuỗi RangeOfString: @" bla ": NSCaseInsensitiveSearch] .location! = NSNotFound)"
Vanja

1
@Dave DeLong Tôi chỉ đề cập đến một Thể loại 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 để trả lời! Vì tôi chủ yếu là nhà phát triển ac #, tôi rất 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 gì nếu mục tiêu triển khai của tôi là iOS7 và tôi sử dụng chứaString?
Ricardo

3
Và để biết thêm về điểm được tạo bởi @Vanja: nếu bạn sẽ sử dụng mã phím tắt [chuỗi chứaString] đã được giới thiệu trong iOS 8 / Yosemite, bạn có thể sử dụng mã sau đây cho chuỗi không phân biệt chữ hoa chữ thường: "[stringToSearch localizedCaseInsensitiveContainsString: string ] ", và cái này nếu bạn muốn thực hiện một tìm kiếm không phân biệt chữ hoa chữ thường:" [stringToSearch localizedSt ChuẩnContainsString: string] ".
Scott Kohlert

1
Lưu ý rằng biểu thức [string rangeOfString:@"bla"].location != NSNotFoundsẽ đúng khi chuỗi là nil!
funroll

158

Đối với iOS 8.0 trở lên và macOS 10.10+, bạn có thể sử dụng bản địa của NSString containsString:.

Đối với các phiên bản iOS và macOS cũ hơn, bạn có thể tạo danh mục (lỗi thời) của riêng mình 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

Lưu ý: Quan sát bình luận của Daniel Galasko bên dưới về cách đặt tên


13
+1 cho mã kết quả rõ ràng hơn và tái sử dụng. 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 mình, es_ios_utils. github.com/peterdeweese/es_ios_utils
Peter De Weese

4
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ập trong câu trả lời của mình. +1
Hồi giáo Q.

7
Quy tắc chính cho các 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ì hiện tại nó mâu thuẫn với bản phát hành iOS 7 và 10.10
Daniel Galasko 17/2/2015

54

Vì đây dường như là một 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 thức vào NSString. Một phiên bản cập nhật của ví dụ của 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");
}

39
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 sau:

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

22

Với iOS 8Swift , chúng ta có thể sử dụng localizedCaseInsensitiveContainsString phương thức

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

 string.localizedCaseInsensitiveContainsString(substring) // true

1
Đ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, vì Swift ra mắt cùng với iOS 8.0. nhưng với swift, bạn vẫn có thể hỗ trợ các thiết bị với iOS 7.
Hemang

13

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

Nhưng một số người có thể không hiểu 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 = nilmã này sẽ sụp đổ. một bài kiểm tra đơ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 sử dụng object-c là cùng một mã sẽ KHÔNG gặp sự cố khi nào 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

Mà rõ ràng KHÔNG phải là những gì bạn muốn.

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

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

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

does string contains string - NO

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

Vui lòng kiểm tra Gist của tôi để biết thêm mã hữu ích.


12

Một phiên bản cải tiến của giải pháp P i , 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 có một phạm vi theo 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));
}

8

Đây là một đoạn 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;
}

Tôi có thể biết lý do tại sao tôi bị hạ cấp? Đó là một đoạn mã làm việc
Durai Amuthan.H

6

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

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

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

5

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

5

Giải pháp tốt nhất. Đơn giản như thế này! Nếu bạn muốn tìm một từ hoặc một phần của chuỗi. Bạn có thể sử dụng mã này. Trong ví dụ này, chúng tôi sẽ kiểm tra xem giá trị của từ có chứa "acter" hay không.

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

5

Trong Swift 4:

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

4

Nếu bạn cần điều này một lần hãy viết:

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;

4

Trong trường hợp nhanh chóng, điều này có thể được sử dụng

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

2

Nếu không bận tâm về chuỗi phân biệt chữ hoa chữ thường. Hãy thử điều này một lần.

NSString *string  = @"Hello World!";

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

1

Vui lòng sử dụng mã này

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

1

Sử dụng tùy chọn NSCaseInsensitiveSearch với RangeOfString: tùy chọn:

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
}

Kết quả đầu ra được tìm thấy: Có

Các tùy chọn có thể được "hoặc" cùng nhau và bao gồm:

NSCaseInsensitiveSearch NSLiteralSearch NSBackwardsSearch và hơn thế nữa


0

Chuỗi đầu tiên chứa hoặc không phải chuỗi thứ hai,

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

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

0

Thử cái này:

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

Đối với Mục tiêu-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");
}

0

Swift 4 trở lên

let str = "Hello iam midhun"

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

Mục tiêu-C

NSString *stringData = @"Hello iam midhun";

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

-1
-(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
  }

1
Trong Objective-C, chúng ta có loại 'NSString`. Chúng tôi không có Stringloại. Thứ hai, chúng ta có tất cả các đối tượng. Vì vậy, như là một đối số bạn nên vượt qua NSString. Tôi bỏ phiếu xóa do chất lượng kém của một câu trả lời dưới câu hỏi rất tích cực.
Aleksey Potapov

-2

Nếu cần một vị trí nhất định của chuỗi, mã này sẽ xuất hiện trong Swift 3.0 :

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

let position = string.range(of: substring)?.lowerBound
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.