【问题标题】:Swift startsWith method?Swift 的startsWith 方法?
【发布时间】:2015-12-16 08:12:57
【问题描述】:

在 Swift 中是否有诸如 startsWith() 方法之类的东西?

我基本上是在尝试检查某个字符串是否以另一个字符串开头。我也希望它不区分大小写。

正如您可能知道的那样,我只是在尝试做一个简单的搜索功能,但我似乎在这方面失败了。

这就是我想要的:

输入“sa”应该会给我“San Antonio”、“Santa Fe”等的结果。 输入“SA”或“Sa”甚至“sA”也应该返回“San Antonio”或“Santa Fe”。

我正在使用

self.rangeOfString(find, options: NSStringCompareOptions.CaseInsensitiveSearch) != nil 

在 iOS9 之前,它工作得很好。但是,升级到 iOS9 后,它停止工作,现在搜索区分大小写。

    var city = "San Antonio"
    var searchString = "san "
    if(city.rangeOfString(searchString, options: NSStringCompareOptions.CaseInsensitiveSearch) != nil){
        print("San Antonio starts with san ");
    }

    var myString = "Just a string with san within it"

    if(myString.rangeOfString(searchString, options: NSStringCompareOptions.CaseInsensitiveSearch) != nil){
        print("I don't want this string to print bc myString does not start with san ");
    }

【问题讨论】:

  • 你能举一个具体的例子,其中带有 CaseInsensitiveSearch 的 rangeOfString 不能按预期工作吗?我已经在 iOS 9 模拟器中对其进行了测试,它对我有用。

标签: ios swift


【解决方案1】:

使用 hasPrefix 代替 startsWith

例子:

"hello dolly".hasPrefix("hello")  // This will return true
"hello dolly".hasPrefix("abc")    // This will return false

【讨论】:

  • OP 要求不区分大小写,而您的回答区分大小写
  • 使用"string".lowercased()在比较前将字符串变为小写非常容易
【解决方案2】:

这里是startsWith的Swift扩展实现:

extension String {

  func startsWith(string: String) -> Bool {

    guard let range = rangeOfString(string, options:[.AnchoredSearch, .CaseInsensitiveSearch]) else {
      return false
    }

    return range.startIndex == startIndex
  }

}

示例用法:

var str = "Hello, playground"

let matches    = str.startsWith("hello") //true
let no_matches = str.startsWith("playground") //false

【讨论】:

    【解决方案3】:

    具体回答大小写不敏感前缀匹配:

    在纯 Swift 中(大部分时间推荐)

    extension String {
        func caseInsensitiveHasPrefix(_ prefix: String) -> Bool {
            return lowercased().hasPrefix(prefix.lowercased())
        }
    }
    

    或:

    extension String {
        func caseInsensitiveHasPrefix(_ prefix: String) -> Bool {
            return lowercased().starts(with: prefix.lowercased())
        }
    }
    

    注意:对于空前缀 "",两个实现都将返回 true

    使用基金会range(of:options:)

    extension String {
        func caseInsensitiveHasPrefix(_ prefix: String) -> Bool {
            return range(of: prefix, options: [.anchored, .caseInsensitive]) != nil
        }
    }
    

    注意:对于空前缀 "",它将返回 false

    用正则表达式变得丑陋(我见过......)

    extension String {
        func caseInsensitiveHasPrefix(_ prefix: String) -> Bool {
            guard let expression = try? NSRegularExpression(pattern: "\(prefix)", options: [.caseInsensitive, .ignoreMetacharacters]) else {
                return false
            }
            return expression.firstMatch(in: self, options: .anchored, range: NSRange(location: 0, length: characters.count)) != nil
        }
    }
    

    注意:对于空前缀 "",它将返回 false

    【讨论】:

      【解决方案4】:

      编辑:为 Swift 3 更新。

      Swift String 类确实有区分大小写的方法hasPrefix(),但如果你想要不区分大小写的搜索,可以使用NSString 方法range(of:options:)

      注意:默认情况下,NSString 方法可用,但如果您import Foundation 它们是可用的。

      所以:

      import Foundation
      var city = "San Antonio"
      var searchString = "san "
      let range = city.range(of: searchString, options:.caseInsensitive)
      if let range = range {
          print("San Antonio starts with san at \(range.startIndex)");
      }
      

      选项可以是.caseInsensitive[.caseInsensitive]。如果您想使用其他选项,您可以使用第二个,例如:

      let range = city.range(of: searchString, options:[.caseInsensitive, .backwards])
      

      这种方法还有一个优点是可以在搜索中使用其他选项,例如.diacriticInsensitive 搜索。仅在字符串上使用. lowercased() 无法达到相同的结果。

      【讨论】:

        【解决方案5】:

        在 swift 4 func starts<PossiblePrefix>(with possiblePrefix: PossiblePrefix) -> Bool where PossiblePrefix : Sequence, String.Element == PossiblePrefix.Element 将被介绍。

        使用示例:

        let a = 1...3
        let b = 1...10
        
        print(b.starts(with: a))
        // Prints "true"
        

        【讨论】:

          【解决方案6】:

          在带有扩展的 Swift 4 中

          我的扩展示例包含 3 个函数:检查使用 subString 执行 String start,对 subString 执行 String end 并执行 String contains 一个子字符串。

          将isCaseSensitive-parameter设置为false,如果要忽略字符“A”或“a”,否则设置为true。

          有关其工作原理的更多信息,请参阅代码中的 cmets。

          代码:

              import Foundation
          
              extension String {
                  // Returns true if the String starts with a substring matching to the prefix-parameter.
                  // If isCaseSensitive-parameter is true, the function returns false,
                  // if you search "sA" from "San Antonio", but if the isCaseSensitive-parameter is false,
                  // the function returns true, if you search "sA" from "San Antonio"
          
                  func hasPrefixCheck(prefix: String, isCaseSensitive: Bool) -> Bool {
          
                      if isCaseSensitive == true {
                          return self.hasPrefix(prefix)
                      } else {
                          var thePrefix: String = prefix, theString: String = self
          
                          while thePrefix.count != 0 {
                              if theString.count == 0 { return false }
                              if theString.lowercased().first != thePrefix.lowercased().first { return false }
                              theString = String(theString.dropFirst())
                              thePrefix = String(thePrefix.dropFirst())
                          }; return true
                      }
                  }
                  // Returns true if the String ends with a substring matching to the prefix-parameter.
                  // If isCaseSensitive-parameter is true, the function returns false,
                  // if you search "Nio" from "San Antonio", but if the isCaseSensitive-parameter is false,
                  // the function returns true, if you search "Nio" from "San Antonio"
                  func hasSuffixCheck(suffix: String, isCaseSensitive: Bool) -> Bool {
          
                      if isCaseSensitive == true {
                          return self.hasSuffix(suffix)
                      } else {
                          var theSuffix: String = suffix, theString: String = self
          
                          while theSuffix.count != 0 {
                              if theString.count == 0 { return false }
                              if theString.lowercased().last != theSuffix.lowercased().last { return false }
                              theString = String(theString.dropLast())
                              theSuffix = String(theSuffix.dropLast())
                          }; return true
                      }
                  }
                  // Returns true if the String contains a substring matching to the prefix-parameter.
                  // If isCaseSensitive-parameter is true, the function returns false,
                  // if you search "aN" from "San Antonio", but if the isCaseSensitive-parameter is false,
                  // the function returns true, if you search "aN" from "San Antonio"
                  func containsSubString(theSubString: String, isCaseSensitive: Bool) -> Bool {
          
                      if isCaseSensitive == true {
                          return self.range(of: theSubString) != nil
                      } else {
                          return self.range(of: theSubString, options: .caseInsensitive) != nil
                      }
                  }
              }
          

          使用示例:

          为了检查字符串是否以“TEST”开头:

              "testString123".hasPrefixCheck(prefix: "TEST", isCaseSensitive: true) // Returns false
              "testString123".hasPrefixCheck(prefix: "TEST", isCaseSensitive: false) // Returns true
          

          为了检查字符串是否以“test”开头:

              "testString123".hasPrefixCheck(prefix: "test", isCaseSensitive: true) // Returns true
              "testString123".hasPrefixCheck(prefix: "test", isCaseSensitive: false) // Returns true
          

          检查字符串是否以“G123”结尾:

              "testString123".hasSuffixCheck(suffix: "G123", isCaseSensitive: true) // Returns false
              "testString123".hasSuffixCheck(suffix: "G123", isCaseSensitive: false) // Returns true
          

          检查字符串是否以“g123”结尾:

              "testString123".hasSuffixCheck(suffix: "g123", isCaseSensitive: true) // Returns true
              "testString123".hasSuffixCheck(suffix: "g123", isCaseSensitive: false) // Returns true
          

          检查字符串是否包含“RING12”:

              "testString123".containsSubString(theSubString: "RING12", isCaseSensitive: true) // Returns false
              "testString123".containsSubString(theSubString: "RING12", isCaseSensitive: false) // Returns true
          

          检查字符串是否包含“ring12”:

              "testString123".containsSubString(theSubString: "ring12", isCaseSensitive: true) // Returns true
              "testString123".containsSubString(theSubString: "ring12", isCaseSensitive: false) // Returns true
          

          【讨论】:

            【解决方案7】:

            Swift 3 版本:

            func startsWith(string: String) -> Bool {
                guard let range = range(of: string, options:[.caseInsensitive]) else {
                    return false
                }
                return range.lowerBound == startIndex
            }
            

            【讨论】:

            • 使用.anchored 可以更快。请参阅我的答案或 Oliver Atkinson 的答案。
            猜你喜欢
            • 1970-01-01
            • 2018-09-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-07-30
            • 1970-01-01
            • 2016-12-10
            • 1970-01-01
            相关资源
            最近更新 更多