【问题标题】:How do I check if a string contains another string in Swift?如何在 Swift 中检查一个字符串是否包含另一个字符串?
【发布时间】:2014-07-24 21:40:27
【问题描述】:

Objective-C 中,检查NSString 中子字符串的代码是:

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

但是如何在 Swift 中做到这一点?

【问题讨论】:

  • 如果您还在,请将接受的答案更改为 user1021430 的答案...正确

标签: swift string nsstring substring


【解决方案1】:

你可以照你说的做:

import Foundation
...
string.contains("Swift");

来自文档:

Swift 的 String 类型无缝连接到 Foundation 的 NSString 班级。如果您正在使用 Cocoa 中的 Foundation 框架或 Cocoa Touch,整个NSString API 可用于调用任何 String 您创建的值,以及所描述的字符串功能 在这一章当中。您还可以将字符串值与任何 API 一起使用 需要一个 NSString 实例。

您需要import Foundation 来桥接NSString 方法并使它们可用于Swift 的String 类。

【讨论】:

  • 不是我,但不,不是。
  • 是的。在 Playground、Mac 应用程序和 iOS 应用程序中进行了尝试。还尝试在 Playground 中导入 Cocoa、UIKit、Foundation 以及它们三者的所有可能组合(Cocoa/UIKit 除外,这没有意义)
  • 从 Swift 1.2 开始不再是这种情况
【解决方案2】:

从文档看来,在 String 上调用 containsString() 应该可行:

Swift 的 String 类型无缝连接到 Foundation 的 NSString 班级。如果您正在使用 Cocoa 中的 Foundation 框架或 Cocoa Touch,整个 NSString API 可以在任何 您创建的字符串值,以及所描述的字符串功能 在这一章当中。您还可以将字符串值与任何 API 一起使用 需要一个 NSString 实例。

但是,它似乎并没有那样工作。

如果您尝试使用someString.containsString(anotherString),您将收到一个编译时错误,指出'String' does not contain a member named 'containsString'

因此,您有几个选择,其中之一是使用 bridgeToObjectiveC() 将您的 String 显式桥接到 Objective-C,另外两个涉及显式使用 NSString,最后一个涉及强制转换StringNSString

通过桥接,你会得到:

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")
}

【讨论】:

  • 最后一个示例(我没有尝试过其他示例)在 iOS 7(设备)上为我崩溃; Swift 应用程序应该在 iOS 7 上运行良好。我得到的错误是 [__NSCFString containsString:]: unrecognized selector sent to instance。另外,我在开发文档中找不到方法 containsString 来确认它是否适用于 iOS 8。
  • 有趣。我只在操场上测试过这个。稍后我会在我的电脑上尝试一下。
  • 第三个和第四个选项是编译器唯一允许的。在 iOS 7 的 beta 4 中,我都崩溃了。
【解决方案3】:

这是我在 swift 操场上的第一次尝试。 我通过提供两个新函数(contains 和 containsIgnoreCase)来扩展 String

extension String {
    func contains(other: String) -> Bool{
        var start = startIndex

        do{
            var subString = self[Range(start: start++, end: endIndex)]
            if subString.hasPrefix(other){
                return true
            }

        }while start != endIndex

        return false
    }

    func containsIgnoreCase(other: String) -> Bool{
        var start = startIndex

        do{
            var subString = self[Range(start: start++, end: endIndex)].lowercaseString
            if subString.hasPrefix(other.lowercaseString){
                return true
            }

        }while start != endIndex

        return false
    }
}

这样使用

var sentence = "This is a test sentence"
sentence.contains("this")  //returns false
sentence.contains("This")  //returns true
sentence.containsIgnoreCase("this")  //returns true

"This is another test sentence".contains(" test ")    //returns true

我欢迎任何反馈:)

【讨论】:

  • 下一步:使它成为适用于所有 Collection 的通用函数 :-) 例如签出startsWith() 内置函数。在“忽略大小写”变体中,仅将字符串小写一次(在执行之前让 lc = other.lowercaseString)
【解决方案4】:

您可以使用 Swift 进行完全相同的调用:

斯威夫特 4 和斯威夫特 5

在 Swift 4 中 String 是 Character 值的集合,在 Swift 2 和 3 中不是这样的,所以你可以使用这个更简洁的代码1

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

斯威夫特 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")
}

老斯威夫特

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

PS。别忘了import Foundation

脚注

  1. 请记住,在字符串上使用集合函数有一些edge cases 可能会给您带来意想不到的结果,例如。 G。在处理表情符号或其他字素簇(如重音字母)时。

【讨论】:

  • Apple 的文档说:An NSRange structure giving the location and length in the receiver of the first occurrence of aString. Returns {NSNotFound, 0} if aString is not found or is empty (@""). 所以也许仅仅检查nil 将无法正常工作。
  • string.lowercaseString.rangeOfString("swift").location != NSNotFound。请阅读文档.. 你不会得到一个 nil 对象。
  • @TheGamingArt 是的,你会的。 Swift 会自动为您往返整个过程,因此如果 NSRange 为 {NSNotFound, 0},它会为您表示为 nil。如果它是一个实际范围,它会为您表示为 Swift Range(可选)。酷。
  • Grr。 containsString 不在文档中,即使在 Xcode 6.3.1 中也是如此。
  • @TheGoonie:这不是打电话给NSString.rangeOfString()。这是调用String.rangeOfString(),它被声明为func rangeOfString(aString: String, options mask: NSStringCompareOptions = default, range searchRange: Range<Index>? = default, locale: NSLocale? = default) -> Range<Index>?
【解决方案5】:

string.containsString 仅适用于 10.10 Yosemite(可能还有 iOS8)。 在 10.9 中还将它桥接到 ObjectiveC 崩溃。您正在尝试将 NSString 传递给 NSCFString。我不知道有什么区别,但是当它在 OS X 10.9 应用程序中执行此代码时,我可以说 10.9 barfs。

以下是 Swift 与 10.9 和 10.10 的区别: https://developer.apple.com/library/prerelease/mac/documentation/General/Reference/APIDiffsMacOSX10_10SeedDiff/index.html containsString 仅在 10.10 中可用

上面的字符串范围在 10.9 上效果很好。我发现使用 Xcode beta2 在 10.9 上进行开发非常稳定。我不通过操场或命令行版本的操场使用操场。我发现如果导入了正确的框架,自动完成功能非常有用。

【讨论】:

    【解决方案6】:

    这里只是答案的附录。

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

     - (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 Release Notes Cocoa 基础框架

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

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

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

    【讨论】:

    • 注意这种方法需要 iOS 8。
    【解决方案7】:

    在这里的所有答案中,我认为它们要么不起作用,要么有点像 hack(转换回 NSString)。这个问题的正确答案很可能随着不同的 beta 版本而改变。

    这是我使用的:

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

    Beta 5 需要“!= nil”。

    【讨论】:

      【解决方案8】:

      扩展方式

      斯威夫特 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+ 中可用


      斯威夫特 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
      

      【讨论】:

      • 忽略大小写使用 return self.rangeOfString(find, options: NSStringCompareOptions.CaseInsensitiveSearch) != nil
      • 不再需要,除非你周围没有Foundation...containsString 工作正常。
      • 对于 swift 3.0.改为以下: extension String { func contains(find: String) -> Bool{ return self.range(of: find) != nil } func containsIgnoringCase(find: String) -> Bool{ return self.range(of: find , 选项:.caseInsensitive) != nil } }
      • 对于 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 } }
      【解决方案9】:
      // Search string exist in employee name finding.
      var empName:NSString! = employeeDetails[filterKeyString] as NSString
      
      Case sensitve search.
      let rangeOfSearchString:NSRange! = empName.rangeOfString(searchString, options: NSStringCompareOptions.CaseInsensitiveSearch)
      
      // Not found.
      if rangeOfSearchString.location != Foundation.NSNotFound
      {
          // search string not found in employee name.
      }
      // Found
      else
      {
          // search string found in employee name.
      }
      

      【讨论】:

        【解决方案10】:

        在 iOS 8 和更新版本中,您可以使用这两个 NSString 方法:

        @availability(iOS, introduced=8.0)
        func containsString(aString: String) -> Bool
        
        @availability(iOS, introduced=8.0)
        func localizedCaseInsensitiveContainsString(aString: String) -> Bool
        

        【讨论】:

        • 什么?看起来它不可用?在xcode 6.1自带的版本中
        【解决方案11】:

        您可以使用以下代码在 Swift 中非常轻松地做到这一点:

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

        【讨论】:

          【解决方案12】:

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

          斯威夫特 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
          }
          

          【讨论】:

            【解决方案13】:

            您无需为此编写任何自定义代码。从 1.2 版本开始,Swift 已经拥有了你需要的所有方法:

            • 获取字符串长度:count(string);
            • 检查字符串是否包含子字符串:contains(string, substring);
            • 检查字符串是否以子字符串开头:startsWith(string, substring)
            • 等等

            【讨论】:

            • Swift 2 不一样。
            • Swift 2: string.hasPrefix(“start”)
            【解决方案14】:

            你在这里:

            let s = "hello Swift"
            if let textRange = s.rangeOfString("Swift") {
                NSLog("exists")
            }
            

            【讨论】:

            • 有时你可能需要一个紧凑的形式,如下所示: let rangeIfExists = string.rangeOfString("Swift") ?? false 如果不包含则返回 false 作为布尔值,否则返回 NSRange
            【解决方案15】:

            我发现了几个有趣的用例。这些变体使用 rangeOfString 方法,我包含了相等示例来展示如何最好地使用 Swift 2.0 中字符串的搜索和比较功能

            //In viewDidLoad() I assign the current object description (A Swift String) to self.loadedObjectDescription
            self.loadedObjectDescription = self.myObject!.description
            

            稍后在我对 self.myObject 进行更改后,我可以参考 以下字符串比较例程(设置为惰性变量 返回一个布尔值)。这允许人们随时检查状态。

            lazy var objectHasChanges : Bool = {
                    guard self.myObject != nil else { return false }
                    return !(self.loadedObjectDescription == self.myObject!.description)
                }()
            

            有时我需要分析丢失的数据时会发生这种情况 该对象的属性。字符串搜索允许我找到 将特定子字符串设置为 nil(创建对象时的默认值)。

                lazy var isMissingProperty : Bool = {
                    guard self.myObject != nil else { return true }
                    let emptyPropertyValue = "myProperty = nil"
                    return (self.myObject!.description.rangeOfString(emptyPropertyValue) != nil) ? true : false
                }()
            

            【讨论】:

              【解决方案16】:

              截至 Xcode 7.1 和 Swift 2.1 containsString() 对我来说工作正常。

              let string = "hello swift"
              if string.containsString("swift") {
                  print("found 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
              

              【讨论】:

              • 你需要import Foundation,否则这不起作用。
              • import UIKitimport Foundation 是必需的,至少在 iOS 11 和 Swift 4 中是这样。
              • 但这区分大小写。你如何在忽略大小写的情况下进行比较。就像在 java String.equalsIgnoreCase(anotherString) 中一样?
              • @zulkarnainshah 我在答案中添加了一个示例。
              • @MurraySagal 那仍然不是不区分大小写的搜索。您将原始字符串转换为小写,然后将其与小写字符串进行显式比较。它会完成这项工作,但这不是理想的方式
              【解决方案17】:

              Xcode 8/Swift 3 版本:

              let string = "hello Swift"
              
              if let range = string.range(of: "Swift") {
                  print("exists at range \(range)")
              } else {
                  print("does not exist")
              }
              
              if let lowercaseRange = string.lowercased().range(of: "swift") {
                  print("exists at range \(lowercaseRange)")
              } else {
                  print("does not exist")
              }
              

              你也可以使用contains:

              string.contains("swift") // false
              string.contains("Swift") // true
              

              【讨论】:

                【解决方案18】:

                给你!为 Xcode 8 和 Swift 3 做好准备。

                import UIKit
                
                let mString = "This is a String that contains something to search."
                let stringToSearchUpperCase = "String"
                let stringToSearchLowerCase = "string"
                
                mString.contains(stringToSearchUpperCase) //true
                mString.contains(stringToSearchLowerCase) //false
                mString.lowercased().contains(stringToSearchUpperCase) //false
                mString.lowercased().contains(stringToSearchLowerCase) //true
                

                【讨论】:

                  【解决方案19】:

                  >在 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
                  

                  【讨论】:

                    【解决方案20】:

                    在 Swift 3 中

                    if((a.range(of: b!, options: String.CompareOptions.caseInsensitive, range: nil, locale: nil)) != nil){
                        print("Done")
                    }
                    

                    【讨论】:

                      【解决方案21】:

                      检查它是否包含'Hello'

                      let s = "Hello World"
                      
                      if s.rangeOfString("Hello") != nil {
                          print("Yes it contains 'Hello'")
                      }
                      

                      【讨论】:

                        【解决方案22】:

                        Swift 3:在这里,您可以看到我的智能搜索扩展,它可以让您搜索字符串以查看它是否包含,或者根据搜索文本过滤集合。

                        https://github.com/magonicolas/Swift-Smart-String-Search

                        【讨论】:

                          【解决方案23】:

                          在 Swift 4.2 中

                          使用

                          func contains(_ str: String) -> Bool
                          

                          示例

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

                          【讨论】:

                          • 请注意,这需要您导入 Foundation。
                          【解决方案24】:

                          SWIFT 4 非常简单!!

                          if (yourString.contains("anyThing")) {
                             print("Exist")
                          }
                          

                          【讨论】:

                          • 这与这里的其他几个答案有何不同?
                          • $ swift Welcome to Apple Swift version 4.2 (swiftlang-1000.11.37.1 clang-1000.11.45.1). Type :help for assistance. 1> print ("Ping") Ping 2> Print ("Ping") error: repl.swift:2:1: error: use of unresolved identifier 'Print' Print ("Ping") ^~~~~ 通过提供未经测试但不起作用的答案。打印!= 打印。
                          【解决方案25】:

                          Swift 4 检查子字符串的方法,包括必要的Foundation(或UIKit)框架导入:

                          import Foundation // or UIKit
                          
                          let str = "Oh Canada!"
                          
                          str.contains("Can") // returns true
                          
                          str.contains("can") // returns false
                          
                          str.lowercased().contains("can") // case-insensitive, returns true
                          

                          除非Foundation(或UIKit)框架被导入,否则str.contains("Can")会给出编译错误。


                          这个答案是反刍manojlds's answer,完全正确。我不知道为什么这么多答案要费力地重新创建FoundationString.contains(subString: String) 方法。

                          【讨论】:

                            【解决方案26】:

                            如果你想检查一个字符串是否包含另一个子字符串,你也可以这样检查,

                            var name = String()  
                            name = "John has two apples." 
                            

                            现在,在这个特定的字符串中,如果你想知道它是否包含水果名称“苹果”,你可以这样做,

                            if name.contains("apple") {  
                              print("Yes , it contains fruit name")    
                            } else {    
                              print("it does not contain any fruit name")    
                            }    
                            

                            希望这对你有用。

                            【讨论】:

                              【解决方案27】:

                              使用 swift 4 中的新语法,您只需

                              string.contains("Swift 4 is the best")

                              string 是你的字符串变量

                              【讨论】:

                                猜你喜欢
                                • 2021-05-06
                                • 2013-03-13
                                • 1970-01-01
                                • 1970-01-01
                                • 2014-04-14
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                相关资源
                                最近更新 更多