大小写不敏感的比较NSString

250

有没有人可以给我提供一些关于 Objective C 中不区分大小写比较的资源?它似乎没有类似于 str1.equalsIgnoreCase(str2) 的方法。

12个回答

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

文档位于搜索和比较方法


157
值得一提的是,如果从其他调用中接收到 @"Some String" 时恰好为 nil,那么您的 if 语句将返回 true,因为向 nil 发送 caseInsensitiveCompare 是有效的,并会导致得到另一个 nil,而在我们的情况下,与 NSOrderedSame 进行比较将返回 trueNSOrderedSame 被定义为 0)。这可能是相当严重的错误来源,正如在我的情况下一样。谢谢! - matm
10
我对此的解决方法是在 NSString 的一个分类中实现该比较为一个方法,并返回一个布尔值。如果接收到的字符串是 nil,则整个方法将返回 NO - Defragged

54
 NSString *stringA;
 NSString *stringB;

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

注意: 因为当stringAnil时,stringA &&是必须的。

 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所指出的,如果someString为nil,这将返回true。 - nh32rg
@nh32rg,你能否通过将if语句更改为类似于if ([someString compare:otherString options:NSCaseInsensitiveSearch] && someString.length > 0 && someString != (id)[NSNull null])的内容来弥补假阳性的问题? - KingPolygon
1
实际上,你需要写成[...comapre:...] == 0,因为如果两个字符串相同,compare返回NSOrderSame(= 0)。对于someString!=(id)[NSNull null],我认为它不是必需的,因为如果为null,则长度为零。我通常这样比较:if(someString.length> 0 && [someString compare:ortherString options:NSCaseIntensitiveSearch] == 0) - Tran Quan

23

在比较之前,您可以始终确保它们处于相同的大小写:

if ([[stringX uppercaseString] isEqualToString:[stringY uppercaseString]]) {
    // They're equal
}
主要的好处是避免了 matm 提到的比较空字符串时可能出现的问题。你可以在使用 compare:options: 方法之前先检查字符串是否为 nil,或者像我一样懒惰,忽略每次比较都创建新字符串的额外成本(如果只进行一两次比较,则成本最小)。

4
操作字母大小写进行比较通常不是个好主意(例如:火鸡测试:http://www.moserware.com/2008/02/does-your-code-pass-turkey-test.html)。当你有语言支持的大小写比较方法(例如`caseInsensitiveCompare`)时,一定要使用它。 - Ohad Schneider

8

iOS 8带来了一种全新的做法。

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

string.localizedCaseInsensitiveContainsString(substring) // true

Objective-C版本:if(string && [string localizedCaseInsensitiveContainsString:substring]) - ski_squaw
OP要求进行“不区分大小写比较”。如果你的解决方案对于“Café”和“É”返回true,那么这绝对不是正确答案。 - Alexander Abakumov

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

12
如果答案带有一些上下文和描述,那么对于人们来说会更加有用。 - jowie

6

以下是将Jason Coco的回答转换为Swift的方法,适用于极度懒惰的人们 :)

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

1
这是针对那些XCode自动补全无法使用的人的提示! :D - Nitin Alabur

6
尝试这种方法。
- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString

5

需要检查像iPhone ContactApp中的前缀。

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

这篇博客对我很有用


1

Swift的备选解决方案:

将两者都转换为大写字母:

e.g:

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

或者将它们都转换成小写:

e.g:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接