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

¿Cómo puedo comprobar 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 cercano 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 averiguar si una cadena contiene otra cadena?

preguntado el 02 de mayo de 10 a las 12:05

Me gustaría verlo agregado también, pero mientras tanto es relativamente fácil agregarlo como una categoría en NSString. -

Usar if ([string rangeOfString:@"hello"] == 0) {...} hay un error de falta de coincidencia de tipos para NSRange e int. para solucionarlo, debe cambiar la línea a lo siguiente: if ([string rangeOfString:@"hello"].length == 0) {...} -

iOS 8 agrega containsString: y aquí hay una forma mínimamente invasiva de agregar compatibilidad con iOS 7 petersteinberger.com/blog/2014/… -

He sido un desarrollador de iOS desde el principio y revisito constantemente esta publicación para copiar y pegar rápidamente. Parece que no puedo memorizar este. La publicación de stackoverflow más visitada de mi historial. -

23 Respuestas

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 darse cuenta de que rangeOfString: devuelve un NSRange estructura y la documentación dice que devuelve la estructura {NSNotFound, 0} si el "pajar" no contiene la "aguja".


Y si está en iOS 8 o OS X Yosemite, ahora puede hacer: (* NOTA: Esto bloqueará 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");
}

(Así es también como funcionaría en Swift)

👍

Respondido 02 Abr '19, 17:04

Para realizar una búsqueda que no distinga entre mayúsculas y minúsculas, utilice "if ([string rangeOfString: @" bla "opciones: NSCaseInsensitiveSearch] .location! = NSNotFound)" - vanja

@Dave DeLong ¡Solo iba a mencionar una categoría que creé para este propósito antes de leer su edición de la respuesta! Como soy principalmente un desarrollador de ac #, me alegro de que hayan agregado un método contiene a NSSTring. - dherrin79

¿Por qué el compilador no dice nada si mi destino de implementación es iOS7 y uso containsString? - Ricardo

Y para ampliar el punto hecho por @Vanja: si va a usar el código de acceso directo [string containsString] que se introdujo en iOS 8 / Yosemite, puede usar el siguiente código para una cadena que no distinga entre mayúsculas y minúsculas: "[stringToSearch localizedCaseInsensitiveContainsString: string ] ", y este si quieres hacer una búsqueda insensible a mayúsculas y minúsculas:" [stringToSearch localizedStandardContainsString: string] ". - scott kohlert

Tenga en cuenta que la expresión [string rangeOfString:@"bla"].location != NSNotFound se mostrarán verdadero cuando la cuerda es nil! - funroll

Para iOS 8.0+ y macOS 10.10+, puede usar el nativo de NSString containsString:.

Para versiones anteriores de iOS y macOS, puede crear su propia categoría (obsoleta) 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

Nota: Observe el comentario de Daniel Galasko a continuación sobre el nombre

Respondido el 07 de diciembre de 19 a las 03:12

+1 para un código resultante más claro y una reutilización. Lo convertí en un forro return [self rangeOfString:substring].location != NSNotFound; y lo incluí en mi biblioteca de refactorización, es_ios_utils. github.com/peterdeweese/es_ios_utils - Pedro De Weese

Parece que a Apple le gusta tu idea y agregó esta función en iOS 8 y OSx 10.10 (Yosemite) como @DaveDeLong mencionó en su respuesta. +1 - islam q.

La regla fundamental para las categorías obj-c es anteponer el nombre del método con el prefijo del módulo de 3 letras. Este es el ejemplo perfecto, ya que ahora entra en conflicto con la versión de iOS 7 y 10.10: daniel galasco

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

iOS 8 y OS X 10.10 agregan el containsString: método para 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");
}

Respondido el 28 de junio de 17 a las 08:06

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 puede usar lo siguiente:

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

Respondido 01 ago 16, 12:08

Con iOS 8 y rápido, nosotros podemos usar localizedCaseInsensitiveContainsString Método

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

 string.localizedCaseInsensitiveContainsString(substring) // true

respondido 08 mar '18, 05:03

Esto es bueno. No tengo idea de por qué no tenían este método para ios 7 - Lucas

@Lucas, porque Swift se lanzó con iOS 8.0. pero con Swift aún puedes admitir los dispositivos con iOS 7. - Respirar

Así que personalmente realmente odio NSNotFound pero comprende su necesidad.

Pero es posible que algunas personas no comprendan las complejidades de comparar con 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 fallará. una prueba simple sería:

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

resultados en !! CHOQUE !!

2) Lo que no es tan obvio para alguien nuevo en objetivo-c es que el mismo código NO fallará 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

Que 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, por lo que 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

Esos son mis 2 centavos ;-)

Por favor mira mi Esencia para obtener un código más útil.

Respondido 06 ago 15, 08:08

Una versión mejorada de Pila solución, 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));
}

contestado el 23 de mayo de 17 a las 13:05

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

Respondido el 19 de junio de 14 a las 06:06

¿Puedo saber por qué me han votado en contra? Es un fragmento de código que funciona. Durai Amuthan.H

Oneliner (menor cantidad de código. SECO, ya que solo tiene uno NSLog):

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

Respondido el 12 de Septiembre de 13 a las 13:09

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

Respondido el 26 de Septiembre de 15 a las 01:09

prueba esto,

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

Respondido 11 ago 16, 09:08

Mejor solución. ¡Tan simple como esto! Si desea encontrar una palabra o parte de la cadena. Puede utilizar este código. En este ejemplo vamos a comprobar si el valor de word 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");
}

Respondido 22 ago 16, 08:08

En Swift 4:

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

Respondido 08 Feb 18, 10:02

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;

Respondido 24 Abr '15, 15:04

En caso de veloz, esto se puede utilizar

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

Respondido 11 ago 16, 08:08

Si no se preocupe por la cadena que distingue entre mayúsculas y minúsculas. Intente esto una vez.

NSString *string  = @"Hello World!";

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

Respondido 01 ago 16, 12:08

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

Respondido 11 ago 16, 09:08

Utilice 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
}

Se encuentra el resultado de salida: Sí

Las opciones se pueden "combinar" e incluir:

NSCaseInsensitiveSearch NSLiteralSearch NSBackwardsSearch y más

contestado el 07 de mayo de 18 a las 17:05

La primera cadena contiene o no la segunda cadena,

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

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

Respondido el 20 de junio de 18 a las 01:06

Prueba esto:

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

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

respondido 01 mar '19, 07:03

Swift 4 y superior

let str = "Hello iam midhun"

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

Objective-C

NSString *stringData = @"Hello iam midhun";

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

respondido 21 nov., 19:05

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

Respondido el 06 de diciembre de 19 a las 19:12

En Objective-C tenemos el tipo 'NSString'. No tenemos String tipo. En segundo lugar, tenemos todos los objetos. Entonces, como argumento debes pasar NSString. Voto por la eliminación debido a la mala calidad de la respuesta en una pregunta muy activa. - Aleksey Potapov

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

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

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

Respondido el 04 de Septiembre de 16 a las 16:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.