Comparação sem distinção entre maiúsculas e minúsculas NSString

240

Alguém pode me indicar algum recurso sobre comparação sem distinção entre maiúsculas e minúsculas no Objetivo C? Parece não ter um método equivalente parastr1.equalsIgnoreCase(str2)

Tejaswi Yerukalapudi
fonte

Respostas:

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

A documentação está localizada em Métodos de pesquisa e comparação

Jason Coco
fonte
152
Vale ressaltar que no caso de quando @"Some String"é recebido de qualquer outra chamada e passa a ser nil, a sua ifvai dar truecomo enviar caseInsensitiveComparepara nilé válido e resulta em um outro nilque, no nosso caso, em comparação com NSOrderedSameretornará true( NSOrderedSameé definido como 0). Isso pode ser uma fonte de bugs bastante devastadores, como foi no meu caso. Felicidades!
matm
10
Minha solução alternativa para isso é implementar essa comparação como um método dentro de uma categoria NSStringque retorna um booleano. Então, se a sequência de recebimento for nil, o método como um todo retornará NO.
defragged
50
 NSString *stringA;
 NSString *stringB;

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

Nota: stringA && é necessário porque quando stringAé nil:

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

e assim acontece NSOrderedSametambém é definido como 0.

O exemplo a seguir é uma armadilha típica:

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

Uma alternativa se você deseja ter mais controle do que apenas insensibilidade a maiúsculas e minúsculas é:

[someString compare:otherString options:NSCaseInsensitiveSearch];

Pesquisa numérica e insensibilidade diacrítica são duas opções úteis.

desenhado
fonte
4
Conforme observado acima pelo matm, isso retornará true se someString for nulo.
Nh32rg 26/07/2013
@ nh32rg Você poderia apenas compensar o falso positivo, alterando a instrução if para algo comoif ([someString compare:otherString options:NSCaseInsensitiveSearch] && someString.length > 0 && someString != (id)[NSNull null])
KingPolygon
1
na verdade, você precisa escrever [... comapre: ...] == 0, porque compare return NSOrderSame (= 0) se duas strings forem iguais. for, someString! = (id) [NSNull null], não acho necessário, porque, se null, o comprimento será zero. Eu costumo comparar como este: if (someString.length> 0 && [SomeString comparar: opções ortherString: NSCaseIntensitiveSearch] == 0)
Tran Quan
23

Você sempre pode garantir que eles estejam no mesmo caso antes da comparação:

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

O principal benefício é evitar o possível problema descrito pelo matm em relação à comparação de cadeias nulas. Você pode verificar se a sequência não é nula antes de executar um dos compare:options:métodos ou pode ser preguiçoso (como eu) e ignorar o custo adicional de criar uma nova sequência para cada comparação (o que é mínimo se você estiver fazendo apenas uma) ou duas comparações).

Chris Wooden
fonte
3
Manipular a caixa para comparação geralmente não é uma coisa sábia a ser feita (por exemplo, o teste da Turquia: moserware.com/2008/02/does-your-code-pass-turkey-test.html ). Quando você tiver uma comparação de casos com suporte ao idioma (como caseInsensitiveCompare), sempre use isso.
Ohad Schneider
7
- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString
WhirlWind
fonte
12
É muito mais útil para as pessoas se as respostas tiverem algum contexto e descrição.
22412 jowie
7

Uma nova maneira de fazer isso. iOS 8

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

string.localizedCaseInsensitiveContainsString(substring) // true
Govind
fonte
versão objC: if (string && [string localizedCaseInsensitiveContainsString: substring])
ski_squaw 14/15
O PO solicita "Comparação sem distinção entre maiúsculas e minúsculas" . Se sua solução retornar truepara "Café" e "É", essa definitivamente NÃO é uma resposta correta.
Alexander Abakumov
6

Experimente este método

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

Convertendo a resposta de Jason Coco a Swift para os profundamente preguiçosos :)

if ("Some String" .caseInsensitiveCompare("some string") == .OrderedSame)
{
  // Strings are equal.
}
Tasik
fonte
1
é necessário para aqueles cujos XCodes se recusam a completar automaticamente! : D
Nitin Alabur
5

para verificar com o prefixo como no iPhone ContactApp

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

este blog foi útil para mim

iMeMyself
fonte
1

Solução alternativa para rápida:

Para criar os dois UpperCase:

por exemplo:

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

ou para fazer o LowerCase:

por exemplo:

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

No macOS, você pode simplesmente usar -[NSString isCaseInsensitiveLike:], o que retorna BOOLexatamente como -isEqual:.

if ([@"Test" isCaseInsensitiveLike: @"test"])
    // Success
mangerlahn
fonte
-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];
}
abc
fonte