Pregunta ¿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?


1141
2018-05-02 15:34


origen


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


Y si tienes iOS 8 u OS X Yosemite, ahora puedes: (* 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");
}

 


2360
2018-05-02 16:20



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 


155
2017-07-09 02:40



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

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

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

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

35
2018-06-27 12:40



Con iOS 8 y Rápido, nosotros podemos usar localizedCaseInsensitiveContainsString  método

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

 string.localizedCaseInsensitiveContainsString(substring) // true

21
2018-06-25 08:53



Así que personalmente realmente odio NSNotFound pero comprende 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 objetivo-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 Esencia para obtener un código más útil.


12
2017-08-06 06:36



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

11
2018-01-29 23:48



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

8
2017-08-29 15:07



Oneliner (Menor cantidad de código. DRY, ya que solo tiene uno NSLog)

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

6
2018-01-29 23:21