ChatGPT解决这个技术问题 Extra ChatGPT

如何在 Swift 4 中使用字符串子字符串? 'substring(to:)' 已弃用:请使用带有 'partial range from' 运算符的字符串切片下标

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

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

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

'substring(to:)' 已弃用:请使用带有 'partial range from' 运算符的字符串切片下标。

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

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

D
Dmitry

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

let newStr = str[..<index]

同样代表运算符的部分范围,只需将另一侧留空:

let newStr = str[index...]

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

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

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


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

将子字符串 (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 个示例,使更新我的项目更容易!
C
Community

斯威夫特 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 - 在这方面它并不比核心库差
i
ilnur

在 Swift 4/5 中更短:

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

这仅在您的字符串具有整数时才有效,您不能对实际的字符串后缀参数执行此操作,因此无法回答问题。
您可以添加有关您的案例的更多信息吗?我真的不明白你说“字符串有整数”和“实际后缀参数”是什么意思?您可以在字符串中获取您想要的任何内容的索引,并使用该索引删除您需要的内容。
let string = "hello world" - 不适用于此。在您的情况下,前缀和后缀的参数是整数。方法没有 String 的参数,例如 string.prefix("world")
这不是“我的情况”。这就是这些方法的工作原理。 let string = "Hello world" let firstThree = String(string.prefix(3)) //"Hel" let lastThree = String(string.suffix(3)) //"rld" 只需使用其他答案找到您需要的索引也许会有所帮助:link
T
Tamás Sengel

也可以通过以下方式将代码转换为 Swift 4:

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

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

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

A
August Lin

斯威夫特5

(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..<endIndex),这是迄今为止我发现的最好的解决方案,只需几行代码就可以做到这一点。
这很好用,是迄今为止最简单的解决方案。谢谢!
D
Den

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
J
Johannes

一些有用的扩展:

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) 也许在他们达到令人惊叹的字符串处理的既定目标之前,他们不应该弃用子字符串。
V
Vlad

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

属性 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"

如果你的意思是 substring(with: range) -> self[range]
C
Chhaileng

您可以使用类 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,它还需要能够处理越界。
S
Stephen Rauch

使用 Swift 4 从 String 创建 SubString(前缀和后缀):

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

let prefix = str[...] 而不是 str[..] 缺少单点。
@AbuTaareq,你在说哪一个?让前缀 = str[..
C
Community

我写了一个字符串扩展来替换'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: "+") 示例结果:"1511508780012"

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


注意:选项被强制解包。如有必要,请添加类型安全检查。
A
Abizern

如果您试图只获取特定字符的子字符串,则无需先找到索引,只需使用 prefix(while:) 方法

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

谢谢!我从中学到了很多。如果其他人难以理解语法,请参阅 docs.swift.org/swift-book/LanguageGuide/Closures.html 了解“闭包表达式”和“尾随闭包”。
V
Vincent

编程时,我经常使用纯 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
A
Anurag Bhakuni

希望这会有所帮助:-

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)

j
jayesh kanzariya

使用这种方法,您可以获得特定范围的字符串。您需要传递起始索引,然后传递您想要的字符总数。

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

i
itsji10dra

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

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)])

encodedOffset 的用途是 considered harmful 并将是 deprecated
O
OhhhThatVarun
var str = "Hello, playground"
let indexcut = str.firstIndex(of: ",")
print(String(str[..<indexcut!]))
print(String(str[indexcut!...]))

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


A
Anand Verma

希望它会有所帮助。

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(","))

H
Hamid Shahsavari

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

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