在Swift语言中如何比较两个字符串而忽略大小写?

114

如何在Swift中比较两个字符串而忽略大小写?例如:

var a = "Cash"
var b = "cash"

是否有一种方法,如果我们比较变量a和变量b将返回true?


2
在进行比较之前,您可以将两者都转换为小写。 - Dino Tw
11
注意,一些答案中提到的lowercaseString在某些语言中会失败(例如Straße != STRASSE)。 - Alladinian
@Alladinian,你认为应该如何解决这个问题呢?大多数解决此问题的示例都显示将其转换为全大写或全小写。 - Steve
5
苹果建议使用 caseInsensitiveCompare:localizedCaseInsensitiveCompare:,这两个方法可以进行不区分大小写的比较,并且支持本地化。 - Alladinian
@Alladinian 谢谢,这些是否也适用于你的示例? - Steve
3
当然可以!(您可以尝试使用"Straße".localizedCaseInsensitiveCompare("STRASSE") - 记得导入Foundation库) - Alladinian
17个回答

203

试试这个:

对于较旧的Swift版本:

var a : String = "Cash"
var b : String = "cash"

if(a.caseInsensitiveCompare(b) == NSComparisonResult.OrderedSame){
    println("Et voila")
}

Swift 3+

var a : String = "Cash"
var b : String = "cash"
    
if(a.caseInsensitiveCompare(b) == .orderedSame){
    print("Et voila")
}

14
在Swift 3中,您需要使用a.caseInsensitiveCompare(b) == ComparisonResult.orderedSame。意思是比较字符串a和b是否相等,而且是不区分大小写的比较。 - azhidkov
3
注意:caseInsensitiveCompare(_:) 不包含在 Swift 标准库中,而是属于 Foundation 框架的一部分,因此需要使用 import Foundation - chrisamanse
这种写法有什么优势,比 a.lowercased() == b.lowercased() 更好吗? - jowie
1
@jowie 正如其他评论中提到的那样,使用lower/uppercased()可能会在某些语言上失败。 - cumanzor
1
a.localizedStandardRange(of: b) == a.startIndex..<a.endIndex 对我来说效果更好,而且支持本地化。上述代码并不适用于所有语言(大小写规则可能不同)。此外,如果 a = "Et voila"b = "Et voilà",所有的 localized*Compare() 都会返回 false,但实际上应该是 true。 - Tomn

42

使用caseInsensitiveCompare方法:

let a = "Cash"
let b = "cash"
let c = a.caseInsensitiveCompare(b) == .orderedSame
print(c) // "true"

ComparisonResult 会告诉你哪个单词在字典顺序中排在前面(即靠近字典的前面)。.orderedSame 表示这两个字符串会被排在字典中相同的位置。


.orderedSame”是什么意思?文档只是说“两个操作数相等”。但为什么这里使用了“order”这个词?是否有一些顺序之类的东西?对于字符串,“左操作数小于右操作数”(.orderedAscending)是什么意思? - mfaani
1
比较结果告诉您哪个单词按字典顺序排在前面(即哪个单词更靠近字典的前面)。 ".orderedSame" 表示这两个字符串在字典中将会处于相同的位置。 - Sergey Kalinichenko
1
@Honey .orderedSameComparisonResult.orderSame 的简写...你不必命名类型,因为编译器知道 caseInsensitiveCompare 返回一个 ComparisonResult。"两个操作数相等"——它们根据特定的顺序是相等的......显然,"Cash" 和 "cash" 不是相同的字符串值。"但为什么这里使用了'顺序'这个词?"——因为它是有序比较的结果。其他值是 orderedAscendingorderedDescending......这不仅仅是相同或不同的问题。至于"更小":字符串就像大基数中的数字。 - Jim Balter
2
我觉得这是糟糕的 API 设计。签名不易读懂...如果改为a.caseInsensitiveCompare(b, comparing: .orderedSame)会更易读... - mfaani

27
if a.lowercaseString == b.lowercaseString {
    //Strings match
}

2
纯Swift是这里的最佳选择。不需要Foundation。 - Alexander
4
转换大小写然后比较是错误的。请参考问题下方的评论。 - Jim Balter
2
@JimBalter 我不会说这是“错误”的,因为它回答了OP问题中给出的示例。对于我们这些不需要支持本地化的人来说,这更加简洁! - toddg
9
不,这是错误的。某个东西在一个例子中有效并不重要。这种方法根本不是“更清洁”的。被接受的答案提供了正确、干净的解决方案。 - Jim Balter

18

试一下这个:

var a = "Cash"
var b = "cash"
let result: NSComparisonResult = a.compare(b, options: NSStringCompareOptions.CaseInsensitiveSearch, range: nil, locale: nil)

// You can also ignore last two parameters(thanks 0x7fffffff)
//let result: NSComparisonResult = a.compare(b, options: NSStringCompareOptions.CaseInsensitiveSearch)

结果是NSComparisonResult枚举类型:

enum NSComparisonResult : Int {

    case OrderedAscending
    case OrderedSame
    case OrderedDescending
}
所以你可以使用 if 语句:
if result == .OrderedSame {
    println("equal")
} else {
    println("not equal")
}

如果我没记错的话,范围和区域设置参数是可选的,可以完全省略。 - Mick MacCallum
4
是的,我确实想展示整个方法及其所有参数。 - Greg
你应该在这里得到正确的答案。比较字符串不仅仅是知道它们是否相等。 - Mikael

12

localizedCaseInsensitiveContains:通过执行不区分大小写、针对本地化的搜索,返回接收器是否包含给定字符串。

if a.localizedCaseInsensitiveContains(b) {
    //returns true if a contains b (case insensitive)
}

编辑:

caseInsensitiveCompare : 使用NSCaseInsensitiveSearch作为唯一选项调用compare(_:options:)的结果。

if a.caseInsensitiveCompare(b) == .orderedSame {
    //returns true if a equals b (case insensitive)
}

2
问题是关于比较,而不是包含。 - Jim Balter
如果“a包含b”且“b包含a”,则它们相等。因此,这肯定是一种可能的解决方案,即使它可能不是最有效的方案。 - Philipp Maurer

10

正确的方式:

let a: String = "Cash"
let b: String = "cash"

if a.caseInsensitiveCompare(b) == .orderedSame {
    //Strings match 
}

请注意: ComparisonResult.orderedSame还可以缩写为.orderedSame。

其他方式:

a.

if a.lowercased() == b.lowercased() {
    //Strings match 
}
.
if a.uppercased() == b.uppercased() {
    //Strings match 
}

c.

if a.capitalized() == b.capitalized() {
    //Strings match 
}

6

您可以自己制作:

func equalIgnoringCase(a:String, b:String) -> Bool {
    return a.lowercaseString == b.lowercaseString
}

6
转换大小写后再进行比较是错误的。请查看问题下方的评论。 - Jim Balter

2
电话号码比较示例;使用Swift 4.2
var selectPhone = [String]()

if selectPhone.index(where: {$0.caseInsensitiveCompare(contactsList[indexPath.row].phone!) == .orderedSame}) != nil {
    print("Same value")
} else {
    print("Not the same")
}

1
你可以只用几行代码编写字符串扩展来进行比较。
extension String {

    func compare(_ with : String)->Bool{
        return self.caseInsensitiveCompare(with) == .orderedSame
    } 
}

1

对于Swift 5 忽略大小写比较两个字符串

最初的回答:

//使用caseInsensitiveCompare方法

let string1 = "Hello" let string2 = "hello" if string1.caseInsensitiveCompare(string2) == .orderedSame { print("The strings are equal!") }

var a = "cash"
var b = "Cash"
if(a.caseInsensitiveCompare(b) == .orderedSame){
     print("Ok")
}

这个重复了许多之前的答案。 - HangarRash

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