Сравнение без учета регистра NSString


Ответы:


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

Документация находится в разделе Методы поиска и сравнения.


152
Стоит отметить , что в случае , когда @"Some String"принимается от любого другого вызова и случается nil, ваш ifбудет давать , trueкак отправка caseInsensitiveCompareв nilкорректен и приводит к другой , nilкоторый, в нашем случае, по сравнению с NSOrderedSameвозвратит true( NSOrderedSameопределяется как 0). Это может быть источником довольно разрушительных ошибок, как это было в моем случае. Ура!
Мат

10
Мой обходной путь для этого состоит в том, чтобы реализовать это сравнение как метод внутри категории, NSStringкоторая возвращает логическое значение. Затем, если получена строка nil, метод в целом возвращается NO.
Дефрагментирован

50
 NSString *stringA;
 NSString *stringB;

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

Примечание: stringA && требуется, потому что когда stringAэто nil:

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

и так бывает NSOrderedSameтакже определяется как 0.

Следующий пример - типичная ловушка:

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

46

Альтернатива, если вы хотите больше контроля, чем просто нечувствительность к регистру:

[someString compare:otherString options:NSCaseInsensitiveSearch];

Числовой поиск и диакритическая нечувствительность - два удобных варианта.


4
Как отмечено выше в matm, это вернет true, если someString равно nil.
nh32rg

@ nh32rg Можете ли вы просто восполнить ложный положительный результат, изменив выражение if на что-то вродеif ([someString compare:otherString options:NSCaseInsensitiveSearch] && someString.length > 0 && someString != (id)[NSNull null])
KingPolygon

1
на самом деле вам нужно написать [... comapre: ...] == 0, потому что сравнение возвращает NSOrderSame (= 0), если две строки одинаковы. for, someString! = (id) [NSNull null], я не думаю, что это требуется, потому что если null, то длина равна нулю. Я обычно сравниваю так: if (someString.length> 0 && [someString сравнить: ortherString options: NSCaseIntensitiveSearch] == 0)
Чан Цюань

23

Вы всегда можете убедиться, что они в одном и том же случае перед сравнением:

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

Главное преимущество в том, что вы избегаете потенциальной проблемы, описанной matm, в отношении сравнения нулевых строк. Вы можете либо проверить, что строка не равна нулю, прежде чем выполнять один из compare:options:методов, или вы можете быть ленивым (как я) и игнорировать добавочную стоимость создания новой строки для каждого сравнения (которая минимальна, если вы делаете только один). или два сравнения).


3
Управлять регистром для сравнения обычно не очень разумно (например, тест индейки: moserware.com/2008/02/does-your-code-pass-turkey-test.html ). Если у вас есть сравнение случаев (например caseInsensitiveCompare), поддерживаемое языком , всегда используйте это.
Охад Шнайдер

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

12
Это гораздо полезнее для людей, если ответы имеют некоторый контекст и описание.
Джоуи

7

Новый способ сделать это. iOS 8

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

string.localizedCaseInsensitiveContainsString(substring) // true

версия objC: if (строка && [string localizedCaseInsensitiveContainsString: substring])
ski_squaw,

ОП запрашивает «Сравнение без учета регистра» . Если ваше решение возвращает true«Café» и «É», это определенно НЕ правильный ответ.
Александр Абакумов

6

Попробуйте этот метод

- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString

6

Преобразование ответа Джейсона Коко в Свифта для глубоко ленивых :)

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

1
это необходимо для тех, чьи XCodes отказываются от автозаполнения! : D
Нитин Алабур

5

проверить с префиксом как в iPhone ContactApp

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

этот блог был полезен для меня


1

Альтернативное решение для Swift:

Чтобы сделать оба UpperCase:

например:

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

или сделать оба LowerCase:

например:

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

0

На MacOS вы можете просто использовать -[NSString isCaseInsensitiveLike:], который возвращает так BOOLже, как -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];
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.