Confronto senza distinzione tra maiuscole e minuscole NSString


240

Qualcuno può indicarmi qualsiasi risorsa sul confronto senza distinzione tra maiuscole e minuscole nell'Obiettivo C? Non sembra avere un metodo equivalente astr1.equalsIgnoreCase(str2)

Risposte:


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

La documentazione si trova in Metodi di ricerca e confronto


152
Vale la pena ricordare che nel caso in cui @"Some String"viene ricevuto da qualsiasi altra chiamata e sembra essere nil, il vostro ifdarà truel'invio caseInsensitiveComparea nilè valido e si traduce in un altro nil, che, nel nostro caso, confrontati con NSOrderedSametornerà true( NSOrderedSameè definito come 0). Questo può essere una fonte di bug abbastanza devastanti, come nel mio caso. Saluti!
matm

10
La mia soluzione è di implementare quel confronto come metodo all'interno di una categoria NSStringche restituisce un valore booleano. Quindi se la stringa di ricezione è nil, il metodo nel suo insieme restituisce NO.
Deframmentato il

50
 NSString *stringA;
 NSString *stringB;

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

Nota: stringA && è richiesto perché quando stringAè nil:

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

e così accade NSOrderedSameè anche definito come 0.

L'esempio seguente è una trappola tipica:

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

46

Un'alternativa se si desidera un maggiore controllo della semplice insensibilità ai casi è:

[someString compare:otherString options:NSCaseInsensitiveSearch];

La ricerca numerica e l'insensibilità diacritica sono due opzioni utili.


4
Come notato sopra da matm, questo tornerà vero se someString è zero.
nh32rg,

@ nh32rg Potresti semplicemente rimediare ai falsi positivi, cambiando l'istruzione if in qualcosa del genereif ([someString compare:otherString options:NSCaseInsensitiveSearch] && someString.length > 0 && someString != (id)[NSNull null])
KingPolygon

1
in realtà, devi scrivere [... comapre: ...] == 0, perché confronta return NSOrderSame (= 0) se due stringhe sono uguali. for, someString! = (id) [NSNull null], non credo sia necessario, perché se null, quindi, la lunghezza è zero. Di solito paragone in questo modo: if (someString.length> 0 && [someString compare: ortherString options: NSCaseIntensitiveSearch] == 0)
Tran Quan

23

Puoi sempre assicurarti che siano nello stesso caso prima del confronto:

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

Il vantaggio principale è che eviti il ​​potenziale problema descritto da matm riguardo al confronto di stringhe zero. Puoi verificare che la stringa non sia nulla prima di eseguire uno dei compare:options:metodi, oppure potresti essere pigro (come me) e ignorare il costo aggiuntivo di creare una nuova stringa per ogni confronto (che è minimo se ne stai facendo solo uno o due confronti).


3
Manipolare l'involucro per il confronto di solito non è una cosa saggia da fare (ad esempio, il test del tacchino: moserware.com/2008/02/does-your-code-pass-turkey-test.html ). Quando hai un confronto dei casi supportato dalla lingua (come caseInsensitiveCompare), usalo sempre.
Ohad Schneider,

7
- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString

12
È molto più utile per le persone se le risposte hanno un contesto e una descrizione.
jowie,

7

Un nuovo modo per farlo. iOS 8

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

string.localizedCaseInsensitiveContainsString(substring) // true

versione objC: if (string && [string localizedCaseInsensitiveContainsString: substring])
ski_squaw

L'OP chiede "Confronto insensibile al maiuscolo / minuscolo" . Se la tua soluzione ritorna trueper "Café" e "É", questa NON è sicuramente una risposta corretta.
Alexander Abakumov,

6

Prova questo metodo

- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString

6

Conversione della risposta di Jason Coco in Swift per i profondamente pigri :)

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

1
è necessario per coloro i cui XCode si rifiutano di completare automaticamente! : D
Nitin Alabur,

5

per verificare con il prefisso come in ContactApp per iPhone

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

questo blog mi è stato utile


1

Soluzione alternativa per swift:

Per creare sia UpperCase:

per esempio:

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

o per rendere entrambi LowerCase:

per esempio:

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

0

Su macOS puoi semplicemente usare -[NSString isCaseInsensitiveLike:], che ritorna BOOLesattamente come -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];
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.