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




string substring (14)

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

¿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 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 encontrar si una cadena contiene otra cadena?


Así que personalmente realmente odio a NSNotFound pero entiendo su necesidad.

Pero algunas personas pueden no entender 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 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 object-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

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 más confiable es el siguiente:

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

Lo que para los casos 1 y 2 volverá.

does string contains string - NO

Esos son mis 2 centavos ;-)

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


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

En Swift 4:

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

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

Mejor solución. ¡Tan simple como esto! Si quieres 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 [email protected]"find a word or character here";
if ([word containsString:@"acter"]){
    NSLog(@"It contains acter");
} else {
     NSLog (@"It does not contain acter");
}

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

Si necesitas esto una vez escribe:

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;

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

Una versión mejorada de la solución de P i , una categoría en NSString, que no solo dirá, si se encuentra una cadena 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

Utilízalo 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));
}

prueba esto,

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

NOTA: Esta respuesta ahora es obsoleta.

Crear 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: observar el comentario de Daniel Galasko a continuación con respecto a los nombres


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

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 puedes usar los siguientes también:

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




substring