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)

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


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
 }

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.


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


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

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

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

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

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


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

0

Sur macOS, vous pouvez simplement utiliser -[NSString isCaseInsensitiveLike:]ce qui revient BOOLcomme -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];
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.