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)

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.


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
 }

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.


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).


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

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

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

6

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

if ("Some String" .caseInsensitiveCompare("some string") == .OrderedSame)
{
  // Strings are equal.
}

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


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

0

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

if ([@"Test" isCaseInsensitiveLike: @"test"])
    // Success

-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];
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.