Comparación insensible a mayúsculas y minúsculas NSString

240

¿Alguien puede señalarme algún recurso sobre la comparación entre mayúsculas y minúsculas en el Objetivo C? No parece tener un método equivalente parastr1.equalsIgnoreCase(str2)

Tejaswi Yerukalapudi
fuente

Respuestas:

564
if( [@"Some String" caseInsensitiveCompare:@"some string"] == NSOrderedSame ) {
  // strings are equal except for possibly case
}

La documentación se encuentra en Métodos de búsqueda y comparación.

Jason Coco
fuente
152
Vale la pena mencionar que, en caso de que @"Some String"se recibe de cualquier otra llamada y pasa a ser nil, a su ifdaré truecomo el envío caseInsensitiveComparea niles válida y resultados en otro nil, que, en nuestro caso, en comparación con NSOrderedSamedevolverá true( NSOrderedSamese define como 0). Esto puede ser una fuente de errores bastante devastadores, como lo fue en mi caso. ¡Salud!
matm
10
Mi solución para esto es implementar esa comparación como un método dentro de una categoría NSStringque devuelve un valor booleano. Entonces, si la cadena receptora es nil, el método en su conjunto regresa NO.
Desfragmentado
50
 NSString *stringA;
 NSString *stringB;

 if (stringA && [stringA caseInsensitiveCompare:stringB] == NSOrderedSame) {
     // match
 }

Nota: stringA && es obligatorio porque cuando stringAes nil:

 stringA = nil;
 [stringA caseInsensitiveCompare:stringB] // return 0

y así sucede NSOrderedSametambién se define como 0.

El siguiente ejemplo es un escollo típico:

 NSString *rank = [[NSUserDefaults standardUserDefaults] stringForKey:@"Rank"];
 if ([rank caseInsensitiveCompare:@"MANAGER"] == NSOrderedSame) {
     // what happens if "Rank" is not found in standardUserDefaults
 }
Oh ho
fuente
46

Una alternativa si desea más control que solo la insensibilidad a mayúsculas y minúsculas es:

[someString compare:otherString options:NSCaseInsensitiveSearch];

La búsqueda numérica y la insensibilidad diacrítica son dos opciones útiles.

dibujado hacia adelante
fuente
44
Como se señaló anteriormente por matm, esto devolverá verdadero si someString es nulo.
nh32rg
@ nh32rg ¿Podría compensar el falso positivo cambiando la declaración if a algo así comoif ([someString compare:otherString options:NSCaseInsensitiveSearch] && someString.length > 0 && someString != (id)[NSNull null])
KingPolygon
1
en realidad, necesita escribir [... comapre: ...] == 0, porque compare return NSOrderSame (= 0) si dos cadenas son iguales. para, someString! = (id) [NSNull null], no creo que sea necesario, porque si es nulo, entonces, la longitud es cero. Normalmente comparo así: if (someString.length> 0 && [someString compare: ortherString options: NSCaseIntensitiveSearch] == 0)
Tran Quan
23

Siempre puede asegurarse de que estén en el mismo caso antes de la comparación:

if ([[stringX uppercaseString] isEqualToString:[stringY uppercaseString]]) {
    // They're equal
}

El principal beneficio es que evita el problema potencial descrito por matm con respecto a la comparación de cadenas nulas. Puede verificar si la cadena no es nula antes de hacer uno de los compare:options:métodos, o podría ser vago (como yo) e ignorar el costo adicional de crear una nueva cadena para cada comparación (que es mínimo si solo está haciendo uno) o dos comparaciones).

Chris Wooden
fuente
3
Por lo general, no es aconsejable manipular la carcasa para comparar (por ejemplo, la prueba de Turquía: moserware.com/2008/02/does-your-code-pass-turkey-test.html ). Cuando tenga una comparación de casos compatible con el idioma (como caseInsensitiveCompare), use siempre eso.
Ohad Schneider
7
- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString
Torbellino
fuente
12
Es mucho más útil para las personas si las respuestas tienen algún contexto y descripción.
jowie
7

Una nueva forma de hacer esto. iOS 8

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

string.localizedCaseInsensitiveContainsString(substring) // true
Govind
fuente
versión objC: if (string && [string localizedCaseInsensitiveContainsString: substring])
ski_squaw
El OP pide "Comparación entre mayúsculas y minúsculas" . Si su solución regresa truepara "Café" y "É", esta definitivamente NO es una respuesta correcta.
Alexander Abakumov
6

Prueba este método

- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString
Reena
fuente
6

Convirtiendo la respuesta de Jason Coco a Swift para los profundamente perezosos :)

if ("Some String" .caseInsensitiveCompare("some string") == .OrderedSame)
{
  // Strings are equal.
}
Tasik
fuente
1
es necesario para aquellos cuyos códigos X se niegan a autocompletar! : D
Nitin Alabur
5

para verificar con el prefijo como en la aplicación de contacto de iPhone

([string rangeOfString:prefixString options:NSCaseInsensitiveSearch].location == 0)

este blog me fue útil

iMeMyself
fuente
1

Solución alternativa para swift:

Para hacer ambos UpperCase:

p.ej:

if ("ABcd".uppercased() == "abcD".uppercased()){
}

o para hacer ambos LowerCase:

p.ej:

if ("ABcd".lowercased() == "abcD".lowercased()){
}
FARAZ
fuente
0

En macOS, simplemente puede usar -[NSString isCaseInsensitiveLike:], que devuelve BOOLigual que -isEqual:.

if ([@"Test" isCaseInsensitiveLike: @"test"])
    // Success
Mangerlahn
fuente
-3
NSMutableArray *arrSearchData;  
NSArray *data=[arrNearByData objectAtIndex:i];
NSString *strValue=[NSString stringWithFormat:@"%@", [data valueForKey:@"restName"]];
NSRange r = [strValue rangeOfString:key options:NSCaseInsensitiveSearch];

if(r.location != NSNotFound)
{
     [arrSearchData addObject:data];
}
a B C
fuente