Porównanie bez rozróżniania wielkości liter NSString

240

Czy ktoś może wskazać mi jakiekolwiek zasoby dotyczące porównania bez rozróżniania wielkości liter w celu C? Wydaje się, że nie ma metody równoważnej dostr1.equalsIgnoreCase(str2)

Tejaswi Yerukalapudi
źródło

Odpowiedzi:

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

Dokumentacja znajduje się w Metodach wyszukiwania i porównywania

Jason Coco
źródło
152
Warto wspomnieć, że w przypadku, gdy @"Some String"zostanie odebrane z innego połączenia i tak się stanie nil, ifpodasz truejako, że wysłanie caseInsensitiveComparena niljest ważne i skutkuje innym, nilktóry w naszym przypadku w porównaniu z NSOrderedSamepowróci true( NSOrderedSamejest zdefiniowany jako 0). Może to być źródłem dość niszczycielskich błędów, tak jak w moim przypadku. Twoje zdrowie!
matm
10
Moim obejściem tego problemu jest wdrożenie tego porównania jako metody wewnątrz kategorii, NSStringktóra zwraca wartość logiczną. Następnie, jeśli ciąg otrzymujący jest nil, metoda jako całość zwraca NO.
Defragged
50
 NSString *stringA;
 NSString *stringB;

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

Uwaga: stringA && wymagane jest, bo gdy stringAjest nil:

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

i tak się dzieje NSOrderedSamejest również zdefiniowany jako 0.

Poniższy przykład to typowa pułapka:

 NSString *rank = [[NSUserDefaults standardUserDefaults] stringForKey:@"Rank"];
 if ([rank caseInsensitiveCompare:@"MANAGER"] == NSOrderedSame) {
     // what happens if "Rank" is not found in standardUserDefaults
 }
ohho
źródło
46

Alternatywą, jeśli chcesz mieć większą kontrolę niż tylko rozróżnianie wielkości liter, jest:

[someString compare:otherString options:NSCaseInsensitiveSearch];

Wyszukiwanie numeryczne i niewrażliwość na znaki diakrytyczne to dwie przydatne opcje.

pociągnięty
źródło
4
Jak zauważono powyżej przez matm, to zwróci true, jeśli someString ma wartość zero.
nh32rg
@ nh32rg Czy możesz po prostu nadrobić fałszywy wynik pozytywny, zmieniając wyrażenie if na coś podobnegoif ([someString compare:otherString options:NSCaseInsensitiveSearch] && someString.length > 0 && someString != (id)[NSNull null])
KingPolygon
1
właściwie musisz napisać [... comapre: ...] == 0, ponieważ porównaj return NSOrderSame (= 0), jeśli dwa ciągi są takie same. for, someString! = (id) [NSNull null], nie sądzę, że jest to wymagane, ponieważ jeśli null, to długość wynosi zero. Zwykle porównuję w ten sposób: if (someString.length> 0 && [someString porównaj: ortherString opcje: NSCaseIntensitiveSearch] == 0)
Tran Quan
23

Zawsze możesz upewnić się, że są w tym samym przypadku przed porównaniem:

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

Główną korzyścią jest unikanie potencjalnego problemu opisanego przez matm dotyczącego porównywania ciągów zerowych. Możesz albo sprawdzić, czy łańcuch nie jest zerowy przed wykonaniem jednej z compare:options:metod, albo możesz być leniwy (jak ja) i zignorować dodatkowy koszt tworzenia nowego łańcucha dla każdego porównania (co jest minimalne, jeśli robisz tylko jedną lub dwa porównania).

Chris Wooden
źródło
3
Manipulowanie obudową do porównywania zwykle nie jest mądrym posunięciem (np. Test indyka: moserware.com/2008/02/does-your-code-pass-turkey-test.html ). Jeśli masz porównanie wielkości liter obsługiwane przez język (np. caseInsensitiveCompare), Zawsze używaj tego.
Ohad Schneider,
7
- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString
Trąba powietrzna
źródło
12
Jest to o wiele bardziej przydatne dla ludzi, jeśli odpowiedzi mają jakiś kontekst i opis.
jowie
7

Nowy sposób na zrobienie tego. iOS 8

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

string.localizedCaseInsensitiveContainsString(substring) // true
Govind
źródło
wersja objC: if (string && [string localizedCaseInsensitiveContainsString: substring])
ski_squaw
OP prosi o „porównanie bez rozróżniania wielkości liter” . Jeśli twoje rozwiązanie zwraca true„Café” i „É”, to zdecydowanie NIE jest poprawna odpowiedź.
Alexander Abakumov
6

Wypróbuj tę metodę

- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString
Reena
źródło
6

Konwersja odpowiedzi Jasona Coco na Swift dla głęboko leniwych :)

if ("Some String" .caseInsensitiveCompare("some string") == .OrderedSame)
{
  // Strings are equal.
}
Tasik
źródło
1
jest potrzebny dla tych, których XCodes odmawiają autouzupełniania! : D
Nitin Alabur
5

aby sprawdzić z prefiksem jak w iPhone ContactApp

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

ten blog był dla mnie przydatny

iMeMyself
źródło
1

Alternatywne rozwiązanie dla szybkiego:

Aby zrobić zarówno UpperCase:

na przykład:

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

lub zrobić zarówno LowerCase:

na przykład:

if ("ABcd".lowercased() == "abcD".lowercased()){
}
FARAZ
źródło
0

Na macOS możesz po prostu użyć -[NSString isCaseInsensitiveLike:], który zwraca BOOLtak jak -isEqual:.

if ([@"Test" isCaseInsensitiveLike: @"test"])
    // Success
mangerlahn
źródło
-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
źródło