Как проверить, содержит ли строка другую строку в Objective-C?


1,105

Как проверить, содержит ли строка (NSString) другую меньшую строку?

Я надеялся на что-то вроде:

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

Но ближе я смог найти:

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

Во всяком случае, это лучший способ найти если строка содержит другую строку?

+1

Я хотел бы видеть он добавил также, но в то же время относительно легко добавить его как категорию в NSString. 11 янв. 132013-01-11 01:48:56

+2

Использование 'if ([string rangeOfString: @" hello "] == 0) {...}' существует ошибка несоответствия типа для NSRange и int. Чтобы исправить это, вы должны изменить строку на следующее: 'if ([string rangeOfString: @" hello "]. length == 0) {...}' 11 ноя. 132013-11-11 16:14:30

+1

iOS 8 добавляет containsString: и здесь минимально инвазивная способ добавить поддержку iOS 7 http://petersteinberger.com/blog/2014/retrofitting-containsstring-on-ios-7/ 06 авг. 142014-08-06 03:18:55

  0

С самого начала я был разработчиком iOS, и я постоянно пересматриваю этот пост для быстрой копии , Кажется, я не помню этого. Самый посещаемый пост stackoverflow в моей истории. 04 май. 162016-05-04 19:13:49

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

Ключ заметив, что rangeOfString: возвращает NSRange-структуру, и the documentation says, что она возвращает {NSNotFound, 0}-структуру, если «стог» не содержит «иглу».


И если вы на прошивкой 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"); 
} 

+279

Чтобы сделать поиск без учета регистра, используйте «if ([string rangeOfString: @« bla »options: NSCaseInsensitiveSearch] .location! = NSNotFound)« 28 мар. 122012-03-28 07:28:34

+1

@Dave DeLong Я просто хотел упомянуть категорию, которую я создал для этой цели, прежде чем я прочитайте ваше редактирование в ответ! Поскольку я в первую очередь разработчик C#, я рад, что они добавили метод contains в NSSTring. 05 сен. 142014-09-05 14:11:39

  0

Почему компилятор ничего не говорит, если моя цель развертывания - iOS7, и я использую containsString? 23 окт. 152015-10-23 11:05:44

+2

И для дальнейшего использования @Vanja: если вы собираетесь использовать ярлык кода [string containsString], который был введен в iOS 8/Yosemite, вы можете использовать следующий код для строки, нечувствительной к регистру: «[stringToSearch localizedCaseInsensitiveContainsString: string] ", и этот, если вы хотите сделать случайный и диакритический нечувствительный поиск:" [stringToSearch localizedStandardContainsString: string] ". 28 мар. 162016-03-28 19:53:55

  0

@ScottKohlert Осторожно, '[stringToSearch localizedStandardContainsString: string]' был введен в ** iOS9 **. 05 июл. 162016-07-05 08:06:57

  0

Обратите внимание, что выражение '[string rangeOfString: @" bla "]. Location! = NSNotFound' будет ** true **, когда строка' nil'! 07 окт. 162016-10-07 20:12:02

  0

Чтобы сохранить поддержку iOS7, вы можете добавить containsString: динамически, для iOS8 + этот код ничего не сделает, и будет использоваться true containsString: будет использоваться. '- (void) setupContainsString { \t SEL содержитStringSelector = @selector (containsString :); \t IMP containsStringIMP = imp_implementationWithBlock (^ (идентификатор _self, NSString * строка) {\ \t \t NSRange диапазон = [_self rangeOfString: строка]; \t \t возвращение range.length!= 0; \t}); \t // Метод добавляется только если класс не имеет реализации этого \t class_addMethod ([NSString класс], \t \t \t \t \t containsStringSelector, \t \t \t \t \t containsStringIMP, \t \t \t \t \t «гр @@: "); } ' 02 апр. 172017-04-02 08:27:00

  0

Bro это действительно хороший ответ. У вас есть +1. 15 дек. 172017-12-15 06:32:32


152

ПРИМЕЧАНИЕ: Этот ответ является устаревшим

Создание категории 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: Наблюдайте комментарий Daniel Galasko ниже действующей в отношении Именование

+13

+1 для более четкого кода и повторного использования. Я превратил его в один liner 'return [self rangeOfString: substring] .location! = NSNotFound;' и включил его в мою рефакторинговую библиотеку es_ios_utils. https://github.com/peterdeweese/es_ios_utils 21 июл. 112011-07-21 15:21:34

+4

Похоже, что Apple любит вашу идею и добавила эту функцию в iOS 8 и OSx 10.10 (Yosemite), как упоминалось в его ответе @DaveDeLong. +1 03 янв. 152015-01-03 19:32:58

+5

Основным правилом для категорий obj-c является префикс имени метода с вашим трехбуквенным модулем. Это прекрасный пример, так как теперь он конфликтует с выпуском iOS 7 и 10.10. 17 фев. 152015-02-17 10:38:16


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

6

Oneliner (меньший объем кода. DRY, как и у вас есть только один NSLog):

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

11

Улучшенная версия P i's solution, категория на NSString, что не только сказать, если строка находится в другой строке, но и занимает диапазон, ссылка, является:

@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 

использовать его как:

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

Вот копия и вставки функции сниппет:

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

Могу ли я узнать, почему я занижен? Это рабочий фрагмент кода 08 июл. 152015-07-08 06:05:17


45

Поскольку это, кажется, высокопоставленным результат в Google, я хочу добавить следующее:

IOS 8 и OS X 10,10 добавить метод containsString: к NSString.Обновленный вариант примера Дейва Делонг для этих систем:

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

21

С IOS 8 и Swift, мы можем использовать localizedCaseInsensitiveContainsString метод

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

string.localizedCaseInsensitiveContainsString(substring) // true 
+1

Это хорошо. Не знаю, почему у них не было этого метода для ios 7 02 июл. 142014-07-02 15:02:13

  0

@ Лукас, потому что Swift запущен с iOS 8.0. но с быстрым вы можете поддерживать устройства с iOS 7. 21 сен. 152015-09-21 12:47:59


3

Если вам это нужно один раз написать:

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; 

2

Если вы не беспокоитесь о чувствительной к регистру строке. Попробуйте это один раз.

NSString *string = @"Hello World!"; 

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

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

1

Пожалуйста, используйте этот код

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

12

Так что лично я ненавижу 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"); 

результаты в !! CRASH !!

2) Что не так очевидно для кого-то нового для объектива-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 для получения более полезного кода.


4

попробовать это,

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

3

В случае быстры, это может быть использовано

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

3

Лучшее решение. Как просто! Если вы хотите найти часть слова или . Вы можете использовать этот код. В этом примере мы будем проверять, содержит ли значение слова «acter».

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

-3

Если определенное положение строки необходимо, этот код приходит на место в Swift 3.0:

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

let position = string.range(of: substring)?.lowerBound 

1

В Swift 4:

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