Comparaison insensible à la casse NSString

240

Quelqu'un peut-il m'indiquer des ressources sur la comparaison insensible à la casse dans l'objectif C? Il ne semble pas avoir de méthode équivalente pourstr1.equalsIgnoreCase(str2)

Tejaswi Yerukalapudi
la source

Réponses:

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

La documentation se trouve dans les méthodes de recherche et de comparaison

Jason Coco
la source
152
Il est une valeur que mention dans le cas où @"Some String"est reçu de tout autre appel et se trouve être nil, votre ifdonnera truel'envoi caseInsensitiveCompareà nilest valide et donne lieu à un autre nilqui, dans notre cas, par rapport à NSOrderedSamerenverra true( NSOrderedSameest défini comme 0). Cela peut être une source de bugs assez dévastateurs, comme ce fut le cas dans mon cas. À votre santé!
matm
10
Ma solution consiste à implémenter cette comparaison en tant que méthode dans une catégorie sur NSStringlaquelle renvoie un booléen. Ensuite, si la chaîne de réception est nil, la méthode dans son ensemble retourne NO.
Défraggé le
50
 NSString *stringA;
 NSString *stringB;

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

Remarque: stringA && est obligatoire car quand stringAest nil:

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

et ainsi se produit NSOrderedSameest également défini comme 0.

L'exemple suivant est un piège typique:

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

Une alternative si vous voulez plus de contrôle que la simple insensibilité à la casse est:

[someString compare:otherString options:NSCaseInsensitiveSearch];

La recherche numérique et l'insensibilité diacritique sont deux options pratiques.

dessiné
la source
4
Comme indiqué ci-dessus par matm, cela retournera vrai si someString est nul.
nh32rg
@ nh32rg Pourriez-vous simplement compenser le faux positif, en changeant l'instruction if en quelque chose commeif ([someString compare:otherString options:NSCaseInsensitiveSearch] && someString.length > 0 && someString != (id)[NSNull null])
KingPolygon
1
en fait, vous devez écrire [... comapre: ...] == 0, car compare return NSOrderSame (= 0) si deux chaînes sont identiques. pour, someString! = (id) [NSNull null], je ne pense pas que cela soit nécessaire, car si null, alors, la longueur est nulle. Je compare habituellement comme ceci: if (someString.length> 0 && [someString compare: options ortherString: NSCaseIntensitiveSearch] == 0)
Tran Quan
23

Vous pouvez toujours vous assurer qu'ils sont dans le même cas avant la comparaison:

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

Le principal avantage étant que vous évitez le problème potentiel décrit par matm concernant la comparaison de chaînes nulles. Vous pouvez soit vérifier que la chaîne n'est pas nulle avant de faire l'une des compare:options:méthodes, soit être paresseux (comme moi) et ignorer le coût supplémentaire de création d'une nouvelle chaîne pour chaque comparaison (ce qui est minime si vous n'en faites qu'une ou deux comparaisons).

Chris Wooden
la source
3
Manipuler le boîtier pour comparer n'est généralement pas une bonne chose à faire (par exemple, le test de la dinde: moserware.com/2008/02/does-your-code-pass-turkey-test.html ). Lorsque vous avez une comparaison de cas prise en charge par la langue (comme caseInsensitiveCompare), utilisez toujours cela.
Ohad Schneider
7
- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString
Tourbillon
la source
12
C'est beaucoup plus utile aux gens si les réponses ont un contexte et une description.
jowie
7

Une nouvelle façon de procéder. iOS 8

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

string.localizedCaseInsensitiveContainsString(substring) // true
Govind
la source
version objC: if (string && [string localizedCaseInsensitiveContainsString: substring])
ski_squaw
Le PO demande une "comparaison insensible à la casse" . Si votre solution revient truepour "Café" et "É", ce n'est certainement pas une bonne réponse.
Alexander Abakumov
6

Essayez cette méthode

- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString
Reena
la source
6

Conversion de la réponse de Jason Coco à Swift pour les profondément paresseux :)

if ("Some String" .caseInsensitiveCompare("some string") == .OrderedSame)
{
  // Strings are equal.
}
Tasik
la source
1
c'est nécessaire pour ceux dont les XCodes refusent de compléter automatiquement! : D
Nitin Alabur
5

vérifier avec le préfixe comme dans l'iPhone ContactApp

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

ce blog m'a été utile

je moi moi-même
la source
1

Solution alternative pour swift:

Pour créer UpperCase:

par exemple:

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

ou pour rendre les deux LowerCase:

par exemple:

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

Sur macOS, vous pouvez simplement utiliser -[NSString isCaseInsensitiveLike:]ce qui revient BOOLcomme -isEqual:.

if ([@"Test" isCaseInsensitiveLike: @"test"])
    // Success
mangerlahn
la source
-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
la source