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)

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


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
 }

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.


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


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

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

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

6

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

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

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


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

0

No macOS, você pode simplesmente usar -[NSString isCaseInsensitiveLike:], o que retorna BOOLexatamente como -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];
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.