¿Cómo obtener la subcadena de NSString?

78

Si quiero obtener un valor de NSString @"value:hello World:value", ¿qué debo usar?

El valor de retorno que quiero es @"hello World".

Csabi
fuente
Voto para cerrar esta pregunta porque no está claro lo que pregunta. No hay ninguna indicación en absoluto de exactamente lo que se quiere aquí. ¿Quieres volver "hello World"? return @"hello World". ¿Quiere devolver lo que está entre dos puntos? ¿Quiere quitar todo lo que queda del colon más a la izquierda y todo lo que queda a la derecha del colon más a la derecha? No hay criterios de entrada-salida claramente definidos para esta pregunta (como vemos con la lista resultante de preguntas que resuelven el problema con una gran variedad de enfoques).
nhgrif

Respuestas:

158

Opción 1:

NSString *haystack = @"value:hello World:value";
NSString *haystackPrefix = @"value:";
NSString *haystackSuffix = @":value";
NSRange needleRange = NSMakeRange(haystackPrefix.length,
                                  haystack.length - haystackPrefix.length - haystackSuffix.length);
NSString *needle = [haystack substringWithRange:needleRange];
NSLog(@"needle: %@", needle); // -> "hello World"

Opcion 2:

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^value:(.+?):value$" options:0 error:nil];
NSTextCheckingResult *match = [regex firstMatchInString:haystack options:NSAnchoredSearch range:NSMakeRange(0, haystack.length)];
NSRange needleRange = [match rangeAtIndex: 1];
NSString *needle = [haystack substringWithRange:needleRange];

Sin embargo, este podría ser un poco exagerado para su caso bastante trivial.

Opcion 3:

NSString *needle = [haystack componentsSeparatedByString:@":"][1];

Este crea tres cadenas temporales y una matriz mientras se divide.


Todos los fragmentos asumen que lo que se busca está contenido en la cadena.

Regexident
fuente
Gritó en NSAnchoredSearch ... tal vez NSMatchingAnchored es mejor.
Jonny
74

Aquí hay una respuesta un poco menos complicada:

NSString *myString = @"abcdefg";
NSString *mySmallerString = [myString substringToIndex:4];

Véase también substringWithRange y substringFromIndex

Shaun Neal
fuente
1
Lo siento, esto no responde a la pregunta (cómo obtener una subcadena del medio de una cadena).
Monolo
¿Qué significa eso
Chicowitz
17

Aquí hay una función simple que le permite hacer lo que está buscando:

- (NSString *)getSubstring:(NSString *)value betweenString:(NSString *)separator
{
    NSRange firstInstance = [value rangeOfString:separator];
    NSRange secondInstance = [[value substringFromIndex:firstInstance.location + firstInstance.length] rangeOfString:separator];
    NSRange finalRange = NSMakeRange(firstInstance.location + separator.length, secondInstance.location);

    return [value substringWithRange:finalRange];
}

Uso:

NSString *myName = [self getSubstring:@"This is my :name:, woo!!" betweenString:@":"];
Garett
fuente
1
En caso de que sea esclarecedor, puedo decirles mi razón para votar la otra respuesta. Prefiero escribir dos líneas de código que seis.
Le Mot Juiced
2
El problema es que esas dos líneas de código solo resuelven un caso específico que nunca existirá para nadie, probablemente ni siquiera para la persona que lo solicitó.
Garett
getSubstring:…debe llamarse substringInString:…ya que no le está pasando una subcadena y, por get…lo general, se espera que los métodos que comienzan con pasen un puntero de búfer para escribir. substringFromIndex:crea una subcadena intermedia, que es innecesaria, para eso rangeOfString:options:range:es. Por último, al envolver el fragmento inseguro en un método supuestamente genérico, está enmascarando un error: si el separador existe una o menos veces en la cadena, obtendrá una excepción fuera de rango.
Regexident
14

Usa esto también

NSString *ChkStr = [MyString substringWithRange:NSMakeRange(5, 26)];

Nota: NSMakeRange(start, end)debe ser NSMakeRange(start, end- start);

Abhishek Mishra
fuente
12

Aquí hay una pequeña combinación de @Regexident Option 1 y @Garett responde, para obtener un poderoso cortador de cuerdas entre un prefijo y un sufijo, con MÁS ... Y MÁS palabras en él.

NSString *haystack = @"MOREvalue:hello World:valueANDMORE";
NSString *prefix = @"value:";
NSString *suffix = @":value";
NSRange prefixRange = [haystack rangeOfString:prefix];
NSRange suffixRange = [[haystack substringFromIndex:prefixRange.location+prefixRange.length] rangeOfString:suffix];
NSRange needleRange = NSMakeRange(prefixRange.location+prefix.length, suffixRange.location);
NSString *needle = [haystack substringWithRange:needleRange];
NSLog(@"needle: %@", needle);
Jeffrey Neo
fuente
¡Ahora esto funciona! Probé la opción 1 de Regixident, no funcionó para mí. No puedo pensar por qué. He estado buscando una solución para obtener una cadena dentro de una <i></i>etiqueta en mi proyecto para poner esas cadenas en cursiva. :)
Glenn Posadas