【问题标题】:How can I use String substring in Swift 4? 'substring(to:)' is deprecated: Please use String slicing subscript with a 'partial range from' operator如何在 Swift 4 中使用字符串子字符串? 'substring(to:)' 已弃用:请使用带有 'partial range from' 运算符的字符串切片下标
【发布时间】:2023-03-28 06:48:01
【问题描述】:

我有以下用 Swift 3 编写的简单代码:

let str = "Hello, playground"
let index = str.index(of: ",")!
let newStr = str.substring(to: index)

从 Xcode 9 beta 5 开始,我收到以下警告:

'substring(to:)' 已弃用:请使用带有'部分范围'运算符的String 切片下标。

如何在 Swift 4 中使用这种 具有部分范围的切片下标

【问题讨论】:

  • var str = "Hello, playground" let indexcut = str.firstIndex(of: ",") print(String(str[..

标签: swift swift4


【解决方案1】:

您应该将一侧留空,因此称为“部分范围”。

let newStr = str[..<index]

partial range from 运算符也一样,只是把另一边留空:

let newStr = str[index...]

请记住,这些范围运算符返回 Substring。如果要转成字符串,使用String的初始化函数:

let newStr = String(str[..<index])

您可以阅读有关新子字符串 here 的更多信息。

【讨论】:

  • str[..&lt;index] 返回一个Substring。如果你想让newStr 成为String你必须写:let newStr = "\(str[..&lt;index])"
  • 对单独的Substring 使用字符串插值可能有点令人困惑,因为您真正想要完成的是String 初始化:let newStr = String(str[..&lt;index])
  • 更新我的“索引”值只是一个整数的代码会产生一条错误消息,Cannot subscript a value of type 'String' with an index of type 'PartialRangeUpTo&lt;Int&gt;'。那里必须使用哪些类型的值?
  • @ConfusionTowers, Swift string indices are not integers,这在版本 4 中没有改变。您可能需要str[..&lt;str.index(str.startIndex, offsetBy: 8)] 或类似的东西。请记住,str.indexoffsetBy 函数中的线性时间 操作。
  • @zneak 你可能想要str.prefix(8)
【解决方案2】:

将子字符串 (Swift 3) 转换为字符串切片 (Swift 4)

Swift 3、4 中的示例:

let newStr = str.substring(to: index) // Swift 3
let newStr = String(str[..<index]) // Swift 4

let newStr = str.substring(from: index) // Swift 3
let newStr = String(str[index...]) // Swift 4 

let range = firstIndex..<secondIndex // If you have a range
let newStr = = str.substring(with: range) // Swift 3
let newStr = String(str[range])  // Swift 4

【讨论】:

  • Perfecto,感谢您并排提供 3 个和 4 个示例,让我的项目更新变得更容易!
【解决方案3】:

斯威夫特 5、4

用法

let text = "Hello world"
text[0] // H
text[...3] // "Hell"
text[6..<text.count] // world
text[NSRange(location: 6, length: 3)] // wor

代码

import Foundation

public extension String {
  subscript(value: Int) -> Character {
    self[index(at: value)]
  }
}

public extension String {
  subscript(value: NSRange) -> Substring {
    self[value.lowerBound..<value.upperBound]
  }
}

public extension String {
  subscript(value: CountableClosedRange<Int>) -> Substring {
    self[index(at: value.lowerBound)...index(at: value.upperBound)]
  }

  subscript(value: CountableRange<Int>) -> Substring {
    self[index(at: value.lowerBound)..<index(at: value.upperBound)]
  }

  subscript(value: PartialRangeUpTo<Int>) -> Substring {
    self[..<index(at: value.upperBound)]
  }

  subscript(value: PartialRangeThrough<Int>) -> Substring {
    self[...index(at: value.upperBound)]
  }

  subscript(value: PartialRangeFrom<Int>) -> Substring {
    self[index(at: value.lowerBound)...]
  }
}

private extension String {
  func index(at offset: Int) -> String.Index {
    index(startIndex, offsetBy: offset)
  }
}

【讨论】:

  • 这个功能应该是默认的快速行为。
  • 一定要把它公关到 Swift lib 中:D
  • 这是对 Swift 最丑陋部分的修复。
  • 这是一个糟糕的答案,因为下标运算符隐藏了索引函数的 O(n) 复杂性。一个好的编程 API 只使用下标来表示快速查找。
  • @ragnarius - 在这方面它并不比核心库差
【解决方案4】:

Swift 4/5 更短:

let string = "123456"
let firstThree = String(string.prefix(3)) //"123"
let lastThree = String(string.suffix(3)) //"456"

【讨论】:

    【解决方案5】:

    您的代码到 Swift 4 的转换也可以通过这种方式完成:

    let str = "Hello, playground"
    let index = str.index(of: ",")!
    let substr = str.prefix(upTo: index)
    

    您可以使用下面的代码来创建一个新字符串:

    let newString = String(str.prefix(upTo: index))
    

    【讨论】:

      【解决方案6】:

      Swift5

      (Java的子字符串方法):

      extension String {
          func subString(from: Int, to: Int) -> String {
             let startIndex = self.index(self.startIndex, offsetBy: from)
             let endIndex = self.index(self.startIndex, offsetBy: to)
             return String(self[startIndex..<endIndex])
          }
      }
      

      用法:

      var str = "Hello, Nick Michaels"
      print(str.subString(from:7,to:20))
      // print Nick Michaels
      

      【讨论】:

      • 在 Swift 5 中仍然有效。我正在寻找 Java 样式的子字符串(fromto-1,例如 "Hello".substring(1,4) 返回“ell”)。稍作修改 (startIndex..&lt;endIndex),这是迄今为止我发现的最佳解决方案,只需几行代码即可完成。
      • 这很好用,是迄今为止最简单的解决方案。谢谢!
      【解决方案7】:

      substring(from: index) 转换为 [index...]

      检查样本

      let text = "1234567890"
      let index = text.index(text.startIndex, offsetBy: 3)
      
      text.substring(from: index) // "4567890"   [Swift 3]
      String(text[index...])      // "4567890"   [Swift 4]
      

      【讨论】:

      • 字符在 Swift 4 中已弃用,我认为您必须更改示例以获取 Swift 4 的索引
      • 这对我有帮助。 tnx
      【解决方案8】:

      一些有用的扩展:

      extension String {
          func substring(from: Int, to: Int) -> String {
              let start = index(startIndex, offsetBy: from)
              let end = index(start, offsetBy: to - from)
              return String(self[start ..< end])
          }
      
          func substring(range: NSRange) -> String {
              return substring(from: range.lowerBound, to: range.upperBound)
          }
      }
      

      【讨论】:

      • 有趣,我也是这么想的。 String(line["http://".endIndex...]) 是否比不推荐使用的子字符串更清晰? line.substring(from: "http://".endIndex) 也许在他们达到惊人的字符串处理的既定目标之前,他们不应该弃用子字符串。
      【解决方案9】:

      Swift3 和 Swift4 中的 uppercasedFirstCharacter 便利属性示例。

      Property uppercasedFirstCharacterNew 演示了如何在 Swift4 中使用字符串切片下标。

      extension String {
      
         public var uppercasedFirstCharacterOld: String {
            if characters.count > 0 {
               let splitIndex = index(after: startIndex)
               let firstCharacter = substring(to: splitIndex).uppercased()
               let sentence = substring(from: splitIndex)
               return firstCharacter + sentence
            } else {
               return self
            }
         }
      
         public var uppercasedFirstCharacterNew: String {
            if characters.count > 0 {
               let splitIndex = index(after: startIndex)
               let firstCharacter = self[..<splitIndex].uppercased()
               let sentence = self[splitIndex...]
               return firstCharacter + sentence
            } else {
               return self
            }
         }
      }
      
      let lorem = "lorem".uppercasedFirstCharacterOld
      print(lorem) // Prints "Lorem"
      
      let ipsum = "ipsum".uppercasedFirstCharacterNew
      print(ipsum) // Prints "Ipsum"
      

      【讨论】:

      • 如果你的意思是子字符串(with: range) -> self[range]
      【解决方案10】:

      您可以使用 String 类的扩展来创建自定义 subString 方法,如下所示:

      extension String {
          func subString(startIndex: Int, endIndex: Int) -> String {
              let end = (endIndex - self.count) + 1
              let indexStartOfText = self.index(self.startIndex, offsetBy: startIndex)
              let indexEndOfText = self.index(self.endIndex, offsetBy: end)
              let substring = self[indexStartOfText..<indexEndOfText]
              return String(substring)
          }
      }
      

      【讨论】:

      • 如果这需要一个endIndex,它也需要能够处理越界。
      【解决方案11】:

      使用 Swift 4 从字符串创建子字符串(前缀和后缀):

      let str : String = "ilike"
      for i in 0...str.count {
          let index = str.index(str.startIndex, offsetBy: i) // String.Index
          let prefix = str[..<index] // String.SubSequence
          let suffix = str[index...] // String.SubSequence
          print("prefix \(prefix), suffix : \(suffix)")
      }
      

      输出

      prefix , suffix : ilike
      prefix i, suffix : like
      prefix il, suffix : ike
      prefix ili, suffix : ke
      prefix ilik, suffix : e
      prefix ilike, suffix : 
      

      如果要在 2 个索引之间生成子字符串,请使用:

      let substring1 = string[startIndex...endIndex] // including endIndex
      let subString2 = string[startIndex..<endIndex] // excluding endIndex
      

      【讨论】:

      • 让前缀 = str[...] 而不是 str[..] 缺少单个点。
      • @AbuTaareq,你说的是哪一个?让前缀 = str[..
      【解决方案12】:

      我写了一个字符串扩展来替换'String: subString:'

      extension String {
          
          func sliceByCharacter(from: Character, to: Character) -> String? {
              let fromIndex = self.index(self.index(of: from)!, offsetBy: 1)
              let toIndex = self.index(self.index(of: to)!, offsetBy: -1)
              return String(self[fromIndex...toIndex])
          }
          
          func sliceByString(from:String, to:String) -> String? {
              //From - startIndex
              var range = self.range(of: from)
              let subString = String(self[range!.upperBound...])
              
              //To - endIndex
              range = subString.range(of: to)
              return String(subString[..<range!.lowerBound])
          }
          
      }
      

      用法:"Date(1511508780012+0530)".sliceByString(from: "(", to: "+")

      Example Result : "1511508780012"

      PS:选项被强制解包。请在必要时添加类型安全检查。

      【讨论】:

      • 警告:选项被强制解包。如有必要,请添加类型安全检查。
      【解决方案13】:

      在编程时,我经常使用纯 A-Za-z 和 0-9 的字符串。无需困难的索引操作。此扩展基于普通的旧左/中/右功能。

      extension String {
      
          // LEFT
          // Returns the specified number of chars from the left of the string
          // let str = "Hello"
          // print(str.left(3))         // Hel
          func left(_ to: Int) -> String {
              return "\(self[..<self.index(startIndex, offsetBy: to)])"
          }
      
          // RIGHT
          // Returns the specified number of chars from the right of the string
          // let str = "Hello"
          // print(str.left(3))         // llo
          func right(_ from: Int) -> String {
              return "\(self[self.index(startIndex, offsetBy: self.length-from)...])"
          }
      
          // MID
          // Returns the specified number of chars from the startpoint of the string
          // let str = "Hello"
          // print(str.left(2,amount: 2))         // ll
          func mid(_ from: Int, amount: Int) -> String {
              let x = "\(self[self.index(startIndex, offsetBy: from)...])"
              return x.left(amount)
          }
      }
      

      【讨论】:

      • 好主意!遗憾的是,有必要抽象 Swift 特性,因为它们不断改变事物的工作方式。猜猜他们希望我们所有人都专注于构造而不是生产力。无论如何,我对你的代码做了一些小的更新:pastebin.com/ManWmNnW
      【解决方案14】:

      希望这会有所帮助:-

      var string = "123456789"
      

      如果你想在某个特定索引之后有一个子字符串。

      var indexStart  =  string.index(after: string.startIndex )// you can use any index in place of startIndex
      var strIndexStart   = String (string[indexStart...])//23456789
      

      如果你想在最后删除一些字符串后得到一个子字符串。

      var indexEnd  =  string.index(before: string.endIndex)
      var strIndexEnd   = String (string[..<indexEnd])//12345678
      

      您还可以使用以下代码创建索引:-

      var  indexWithOffset =  string.index(string.startIndex, offsetBy: 4)
      

      【讨论】:

        【解决方案15】:

        使用此方法,您可以获得特定范围的字符串。您需要传递起始索引和所需的总字符数。

        extension String{
            func substring(fromIndex : Int,count : Int) -> String{
                let startIndex = self.index(self.startIndex, offsetBy: fromIndex)
                let endIndex = self.index(self.startIndex, offsetBy: fromIndex + count)
                let range = startIndex..<endIndex
                return String(self[range])
            }
        }
        

        【讨论】:

          【解决方案16】:

          这是我的解决方案,没有警告,没有错误,但是很完美

          let redStr: String = String(trimmStr[String.Index.init(encodedOffset: 0)..<String.Index.init(encodedOffset: 2)])
          let greenStr: String = String(trimmStr[String.Index.init(encodedOffset: 3)..<String.Index.init(encodedOffset: 4)])
          let blueStr: String = String(trimmStr[String.Index.init(encodedOffset: 5)..<String.Index.init(encodedOffset: 6)])
          

          【讨论】:

          【解决方案17】:

          如果你只是想得到一个特定字符的子字符串,你不需要先找到索引,你可以使用prefix(while:)方法

          let str = "Hello, playground"
          let subString = str.prefix { $0 != "," } // "Hello" as a String.SubSequence
          

          【讨论】:

          【解决方案18】:
          var str = "Hello, playground"
          let indexcut = str.firstIndex(of: ",")
          print(String(str[..<indexcut!]))
          print(String(str[indexcut!...]))
          

          你可以这样尝试,会得到正确的结果。

          【讨论】:

            【解决方案19】:

            希望对您有所帮助。

            extension String {
                func getSubString(_ char: Character) -> String {
                    var subString = ""
                    for eachChar in self {
                        if eachChar == char {
                            return subString
                        } else {
                            subString += String(eachChar)
                        }
                    }
                    return subString
                }
            }
            
            
            let str: String = "Hello, playground"
            print(str.getSubString(","))
            

            【讨论】:

              【解决方案20】:

              我使用的最简单的方法是:

              String(Array(str)[2...4])
              

              【讨论】:

                猜你喜欢
                • 2018-03-02
                • 2018-02-05
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-10-11
                • 1970-01-01
                • 2021-03-12
                相关资源
                最近更新 更多