在Swift中如何检查字符串是否包含另一个字符串?

650

Objective-C中,检查一个NSString中是否包含子字符串的代码是:


NSString *string = @"hello Swift";
NSRange textRange =[string rangeOfString:@"Swift"];
if(textRange.location != NSNotFound)
{
    NSLog(@"exists");
}

但是我怎么在Swift中做到这一点呢?


如果您还在,请将已接受的答案更改为用户1021430的答案...它是正确的。 - Dan Rosenstark
Swift 5+:if largeText.contains("stringToSearchFor") { print("yes") } - MBH
28个回答

1265
您可以使用Swift完全相同的调用方式:

Swift 4和Swift 5

在Swift 4中,String是Character值的集合,而在Swift 2和3中并非如此,因此您可以使用这个更简洁的代码1

let string = "hello Swift"
if string.contains("Swift") {
    print("exists")
}

Swift 3.0+

var string = "hello Swift"

if string.range(of:"Swift") != nil { 
    print("exists")
}

// alternative: not case sensitive
if string.lowercased().range(of:"swift") != nil {
    print("exists")
}

旧版Swift

var string = "hello Swift"

if string.rangeOfString("Swift") != nil{ 
    println("exists")
}

// alternative: not case sensitive
if string.lowercaseString.rangeOfString("swift") != nil {
    println("exists")
}

我希望这是一个有用的解决方案,因为一些人,包括我在内,调用 containsString() 时遇到了一些奇怪的问题。1

附注:不要忘记 import Foundation

脚注

  1. 请记住,在字符串上使用集合函数可能会出现一些边缘情况,这可能会给您带来意外的结果,例如处理表情符号或其他字形簇(如重音字母)时。

14
苹果公司的文档说:“返回一个NSRange结构体,其中包含接收器中第一次出现aString的位置和长度。如果未找到aString或aString为空(@“”),则返回{NSNotFound,0}。”因此,仅检查“nil”可能无法正常工作。 - Alex
7
请阅读文档,使用string.lowercaseString.rangeOfString("swift").location != NSNotFound。您将不会得到一个空对象返回。 - TheCodingArt
4
是的,Swift会自动为您快速地往返整个过程,因此如果NSRange为{NSNotFound, 0},则会自动将其表示为nil。 如果它是一个实际范围,则会将其表示为Swift Range(可选)。很酷。 - matt
4
抱歉,containsString方法在文档中并未提及,即使到了Xcode 6.3.1版本也是如此。 - Duncan C
20
@TheGoonie:这不是调用 NSString.rangeOfString() 方法。这是调用 String.rangeOfString() 方法,声明如下:func rangeOfString(aString: String, options mask: NSStringCompareOptions = default, range searchRange: Range<Index>? = default, locale: NSLocale? = default) -> Range<Index>? - newacct
显示剩余16条评论

203

扩展方式

Swift 4

extension String {
    func contains(find: String) -> Bool{
        return self.range(of: find) != nil
    }
    func containsIgnoringCase(find: String) -> Bool{
        return self.range(of: find, options: .caseInsensitive) != nil
    }
}

var value = "Hello world"

print(value.contains("Hello")) // true
print(value.contains("bo"))    // false

print(value.containsIgnoringCase(find: "hello"))    // true
print(value.containsIgnoringCase(find: "Hello"))    // true
print(value.containsIgnoringCase(find: "bo"))       // false

一般来说,Swift 4有contains方法,但它只能在iOS 8.0及以上版本中使用。


Swift 3.1

你可以为String编写contains:containsIgnoringCase扩展。

extension String { 

   func contains(_ find: String) -> Bool{
     return self.range(of: find) != nil
   }

   func containsIgnoringCase(_ find: String) -> Bool{
     return self.range(of: find, options: .caseInsensitive) != nil 
   }
 }

旧版 Swift

extension String {

    func contains(find: String) -> Bool{
       return self.rangeOfString(find) != nil
     }

    func containsIgnoringCase(find: String) -> Bool{
       return self.rangeOfString(find, options: NSStringCompareOptions.CaseInsensitiveSearch) != nil
     }
}

例子:

var value = "Hello world"

print(value.contains("Hello")) // true
print(value.contains("bo"))    // false

print(value.containsIgnoringCase("hello"))    // true
print(value.containsIgnoringCase("Hello"))    // true
print(value.containsIgnoringCase("bo"))       // false

6
若要忽略大小写,请使用 return self.rangeOfString(find, options: NSStringCompareOptions.CaseInsensitiveSearch) != nil。 - masgar
1
除非您没有Foundation,否则不再需要此操作... containsString的效果很好。 - Dan Rosenstark
5
针对Swift 3.0版本进行更改如下:扩展字符串: func contains(find: String) -> Bool{ return self.range(of: find) != nil } func containsIgnoringCase(find: String) -> Bool{ return self.range(of: find, options: .caseInsensitive) != nil } - Michael Shang
对于Swift 4 -> 扩展字符串 {func contains(find: String) -> Bool{ return self.range(of: find) != nil } func containsIgnoringCase(find: String) -> Bool{ return self.range(of: find, options: .caseInsensitive) != nil }} - shokaveli

51

根据文档,调用 containsString() 应该可以在字符串上工作:

Swift的String类型与Foundation的NSString类无缝桥接。如果您正在使用Cocoa或Cocoa Touch的Foundation框架,则可以调用任何创建的String值上的整个NSString API,以及本章描述的String特性。您还可以将String值与需要NSString实例的任何API一起使用。

然而,它似乎并不是这样工作的。

如果您尝试使用someString.containsString(anotherString),则会出现编译时错误,指出'String' does not contain a member named 'containsString'

因此,您有几个选项,其中一个是通过使用bridgeToObjectiveC()显式将您的String桥接到Objective-C,其他两个涉及显式使用NSString,最后一个涉及将String转换为NSString

通过桥接,您将得到:

var string = "hello Swift"
if string.bridgeToObjectiveC().containsString("Swift") {
    println("YES")
}

通过将字符串明确地声明为 NSString,你会得到:

var string: NSString = "hello Swift"
if string.containsString("Swift") {
    println("YES")
}

如果您已经有一个现有的String,您可以使用NSString(string:)来初始化一个NSString:

var string = "hello Swift"
if NSString(string: string).containsString("Swift") {
    println("YES")
}

最后,你可以将现有的String强制转换为NSString如下:

var string = "hello Swift"
if (string as NSString).containsString("Swift") {
    println("YES")
}

4
我尚未尝试其他示例,但最后一个示例在我的iOS 7(设备)上崩溃;Swift应用程序应该可以在iOS 7上正常运行。我遇到的错误是“[__NSCFString containsString:]:未识别的选择器发送给实例”。此外,我无法在开发文档中找到“containsString”方法,以确认它是否是iOS 8中的新功能。 - Jason Leach
有趣。我只在游乐场上测试过这个。等我回到电脑前,我会再试一下的。 - Cezar
编译器仅允许第三和第四个选项。在iOS 7的beta 4中,它们都会使我的程序崩溃。 - Pouria Almassi

41

另一个。支持大小写和发音符选项。

Swift 3.0

struct MyString {
  static func contains(_ text: String, substring: String,
                       ignoreCase: Bool = true,
                       ignoreDiacritic: Bool = true) -> Bool {

    var options = NSString.CompareOptions()

    if ignoreCase { _ = options.insert(NSString.CompareOptions.caseInsensitive) }
    if ignoreDiacritic { _ = options.insert(NSString.CompareOptions.diacriticInsensitive) }

    return text.range(of: substring, options: options) != nil
  }
}

使用方法

MyString.contains("Niels Bohr", substring: "Bohr") // true

iOS 9+

iOS 9已经提供了不区分大小写和音标的函数。

if #available(iOS 9.0, *) {
  "Für Elise".localizedStandardContains("fur") // true
}

31

在Xcode 7.1和Swift 2.1中,containsString()对我来说工作得很好。

let string = "hello swift"
if string.containsString("swift") {
    print("found swift")
}

Swift 4:

let string = "hello swift"
if string.contains("swift") {
    print("found swift")
}

这是一个不区分大小写的 Swift 4 示例:

let string = "Hello Swift"
if string.lowercased().contains("swift") {
    print("found swift")
}

或者使用不区分大小写的 String 扩展:

extension String {
    func containsIgnoreCase(_ string: String) -> Bool {
        return self.lowercased().contains(string.lowercased())
    }
}

let string = "Hello Swift"
let stringToFind = "SWIFT"
if string.containsIgnoreCase(stringToFind) {
    print("found: \(stringToFind)")  // found: SWIFT
}
print("string: \(string)")
print("stringToFind: \(stringToFind)")

// console output:
found: SWIFT
string: Hello Swift
stringToFind: SWIFT

3
否则这将无法正常工作,你需要import Foundation - Andrii Chernenko
在iOS 11和Swift 4中,需要导入import UIKitimport Foundation中的至少一个。 - Murray Sagal
但是那是区分大小写的。在忽略大小写的情况下如何进行比较?就像在Java中使用String.equalsIgnoreCase(anotherString)一样? - zulkarnain shah
@zulkarnainshah,我在答案中添加了一个示例。 - Murray Sagal
@MurraySagal 这仍然不是大小写不敏感的搜索。您正在将原始字符串转换为小写,然后明确地将其与小写字符串进行比较。它可以完成工作,但这不是理想的方法。 - zulkarnain shah
@zulkarnainshah 我添加了另一个示例,显示原始值没有被更改。我想这差不多就是Java的equalsIgnoreCase()containsIgnoreCase()的实现方式。 - Murray Sagal

23

在Swift 4.2中

使用

func contains(_ str: String) -> Bool

例子

let string = "hello Swift"
let containsSwift = string.contains("Swift")
print(containsSwift) // prints true

6
请注意,这需要您导入 Foundation。 - rmaddy

16

在 Swift 3.0 中

let str = "Hello Swift"
if str.lowercased().contains("Swift".lowercased()) {
    print("String Contains Another String")
} else {
    print("Not Exists")
}

输出

String Contains Another String

15

你可以使用以下代码在Swift中轻松实现此操作:

let string = "hello Swift";
let subString = (string as NSString).containsString("Swift")
if(subString){println("Exist")}

10

在这里,我认为所有的答案要么不起作用,要么有点“hacky”(将其强制转换回NSString)。很可能随着不同的beta版本发布,正确的答案已经发生了改变。

这是我使用的方法:

let string: String = "hello Swift"
if string.rangeOfString("Swift") != nil
{
    println("exists")
}

"!= nil" 在 Beta 5 中变成了必需品。


10

在这里添加一点说明。

您还可以使用以下方法进行本地不区分大小写测试:

 - (BOOL)localizedCaseInsensitiveContainsString:(NSString *)aString

示例:

    import Foundation

    var string: NSString  =  "hello Swift"
   if string.localizedCaseInsensitiveContainsString("Hello") {
    println("TRUE")
}

更新

这是iOS和Mac OS X 10.10.x的基础框架的一部分,也是我最初发布时的10.10版本的一部分。

  

文档生成时间:2014-06-05 12:26:27 -0700 OS X发布说明版权所有© 2014 Apple Inc.。保留所有权利。

     

OS X 10.10版本发布说明 Cocoa Foundation Framework

     

NSString现在有以下两个便捷方法:

     

- (BOOL)containsString:(NSString *)str;

     

- (BOOL)localizedCaseInsensitiveContainsString:(NSString *)str;


1
请注意,这种方法要求 iOS 8 或更高版本。 - Andrew Ebling

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