¿Cómo puedo verificar si una cadena contiene otra cadena en Objective-C?

¿Cómo puedo verificar si una cadena ( NSString ) contiene otra cadena más pequeña?

Esperaba algo como:

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

Pero lo más cerca que pude encontrar fue:

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

De todos modos, ¿es esa la mejor manera de encontrar si una cadena contiene otra cadena?

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

La clave es notar que rangeOfString: devuelve una estructura NSRange , y la documentación dice que devuelve la estructura {NSNotFound, 0} si el “pajar” no contiene la “aguja”.


Y si tiene iOS 8 u OS X Yosemite, puede hacer lo siguiente: (* NOTA: Esto PODRÁ colgar su aplicación si se llama a este código en un dispositivo iOS7).

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

👍

NOTA: esta respuesta ahora está obsoleta

Crea una categoría para 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 

EDITAR: Observe el comentario de Daniel Galasko a continuación sobre el nombramiento

Dado que este parece ser un resultado de alto rango en Google, quiero agregar esto:

iOS 8 y OS X 10.10 agregan el método containsString: a NSString . Una versión actualizada del ejemplo de Dave DeLong para esos sistemas:

 NSString *string = @"hello bla bla"; if ([string containsString:@"bla"]) { NSLog(@"string contains bla!"); } else { NSLog(@"string does not contain bla"); } 
 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!"); } 

// Alternativamente, también puedes usar lo siguiente:

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

Con iOS 8 y Swift , podemos usar el método localizedCaseInsensitiveContainsString

  let string: NSString = "Café" let substring: NSString = "É" string.localizedCaseInsensitiveContainsString(substring) // true 

Personalmente, realmente odio NSNotFound pero entiendo su necesidad.

Pero algunas personas pueden no entender las complejidades de comparar contra NSNotFound

Por ejemplo, este código:

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

tiene sus problemas:

1) Obviamente si otherString = nil este código se bloqueará. una prueba simple sería:

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

resultados en !! ¡CRASH!

2) Lo que no es tan obvio para alguien nuevo en el objective-c es que el mismo código NO se bloqueará cuando string = nil . Por ejemplo, este código:

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

y este código:

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

ambos resultarán en

 does string contains string - YES 

Lo cual claramente NO es lo que quieres.

Entonces, la mejor solución que creo que funciona es usar el hecho de que rangeOfString devuelve la longitud de 0 entonces un código mejor y más confiable es este:

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

O SIMPLEMENTE:

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

que para los casos 1 y 2 volverá

 does string contains string - NO 

Esa es mi 2 centavos 😉

Por favor revisa mi Gist para obtener un código más útil.

Una versión mejorada de la solución de P i , una categoría en NSString, que no solo dirá, si una cadena se encuentra dentro de otra cadena, sino que también toma un rango por referencia, es:

 @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 

Úselo como:

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

Aquí hay un fragmento de función de copiar y pegar:

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

Oneliner (Cantidad menor de código. DRY, ya que solo tiene un NSLog ):

 NSString *string = @"hello bla bla"; NSLog(@"String %@", ([string rangeOfString:@"bla"].location == NSNotFound) ? @"not found" : @"cotains bla"); 
 NSString *categoryString = @"Holiday Event"; if([categoryString rangeOfString:@"Holiday"].location == NSNotFound) { //categoryString does not contains Holiday } else { //categoryString contains Holiday } 

prueba esto,

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

Si necesita esto una vez, escriba:

 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; 

En caso de rapidez, esto puede ser utilizado

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

Mejor solución. ¡Tan simple como esto! Si quieres encontrar una palabra o parte de la cadena. Puedes usar este código En este ejemplo, vamos a verificar si el valor de la palabra contiene “acter”.

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

En Swift 4:

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

Si no te molestas sobre la cadena sensible a mayúsculas y minúsculas. Prueba esto una vez.

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

Por favor usa este código

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

Use la opción NSCaseInsensitiveSearch con rangeOfString: opciones:

 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 } 

Resultado de salida se encuentra: Sí

Las opciones se pueden “juntar” e incluir:

NSCaseInsensitiveSearch NSLiteralSearch NSBackwardsSearch y más

La primera cadena contiene o no segunda cuerda,

 NSString *first = @"Banana"; NSString *second = @"BananaMilk"; NSRange range = [first rangeOfString:second options:NSCaseInsensitiveSearch]; if (range.length > 0) { NSLog(@"Detected"); } else { NSLog(@"Not detected"); } 

Si se necesita cierta posición de la cadena, este código aparece en Swift 3.0 :

 let string = "This is my string" let substring = "my" let position = string.range(of: substring)?.lowerBound