我一直在更新我的一些旧代码和答案与Swift 3,但当我得到Swift字符串和索引子字符串的事情变得令人困惑。

具体来说,我尝试了以下几点:

let str = "Hello, playground"
let prefixRange = str.startIndex..<str.startIndex.advancedBy(5)
let prefix = str.substringWithRange(prefixRange)

第二行给出了如下错误

String类型的值没有成员substringWithRange

我看到String现在确实有以下方法:

str.substring(to: String.Index)
str.substring(from: String.Index)
str.substring(with: Range<String.Index>)

这些一开始让我很困惑,所以我开始摆弄索引和范围。这是子字符串的后续问题和答案。我在下面添加了一个答案来说明它们是如何使用的。


当前回答

我是Swift 3的新手,但看看字符串(索引)语法类比,我认为索引就像一个“指针”约束到字符串和Int可以帮助作为一个独立的对象。使用base + offset语法,然后我们可以用下面的代码从string中获得第i个字符:

let s = "abcdefghi"
let i = 2
print (s[s.index(s.startIndex, offsetBy:i)])
// print c

对于字符串中使用string (range)语法的字符范围(索引),我们可以使用下面的代码获得从第i个字符到第f个字符:

let f = 6
print (s[s.index(s.startIndex, offsetBy:i )..<s.index(s.startIndex, offsetBy:f+1 )])
//print cdefg

对于字符串中的子字符串(range),使用string。Substring (range),我们可以使用下面的代码获得子字符串:

print (s.substring (with:s.index(s.startIndex, offsetBy:i )..<s.index(s.startIndex, offsetBy:f+1 ) ) )
//print cdefg

注:

第i和f以0开头。 对于f-th,我使用offsetBY: f + 1,因为订阅的范围使用..<(半开操作符),不包括第f个位置。 当然必须包括无效索引等验证错误。

其他回答

我是Swift 3的新手,但看看字符串(索引)语法类比,我认为索引就像一个“指针”约束到字符串和Int可以帮助作为一个独立的对象。使用base + offset语法,然后我们可以用下面的代码从string中获得第i个字符:

let s = "abcdefghi"
let i = 2
print (s[s.index(s.startIndex, offsetBy:i)])
// print c

对于字符串中使用string (range)语法的字符范围(索引),我们可以使用下面的代码获得从第i个字符到第f个字符:

let f = 6
print (s[s.index(s.startIndex, offsetBy:i )..<s.index(s.startIndex, offsetBy:f+1 )])
//print cdefg

对于字符串中的子字符串(range),使用string。Substring (range),我们可以使用下面的代码获得子字符串:

print (s.substring (with:s.index(s.startIndex, offsetBy:i )..<s.index(s.startIndex, offsetBy:f+1 ) ) )
//print cdefg

注:

第i和f以0开头。 对于f-th,我使用offsetBY: f + 1,因为订阅的范围使用..<(半开操作符),不包括第f个位置。 当然必须包括无效索引等验证错误。

Swift 4和5:

extension String {
  subscript(_ i: Int) -> String {
    let idx1 = index(startIndex, offsetBy: i)
    let idx2 = index(idx1, offsetBy: 1)
    return String(self[idx1..<idx2])
  }

  subscript (r: Range<Int>) -> String {
    let start = index(startIndex, offsetBy: r.lowerBound)
    let end = index(startIndex, offsetBy: r.upperBound)
    return String(self[start ..< end])
  }

  subscript (r: CountableClosedRange<Int>) -> String {
    let startIndex =  self.index(self.startIndex, offsetBy: r.lowerBound)
    let endIndex = self.index(startIndex, offsetBy: r.upperBound - r.lowerBound)
    return String(self[startIndex...endIndex])
  }
}

如何使用:

"abcde"[0] -> "a" “中的”[0…2]——>“abc” ”中的“[2 . .<4]——> "cd"

var str = "VEGANISM"
print (str[str.index(str.startIndex, offsetBy:2)..<str.index(str.endIndex, offsetBy: -1)] )

//Output-> GANIS

这里str.startIndex和str.endIndex是字符串的起始索引和结束索引。

这里作为startIndex = 2 -> str.index(str. index)中的offsetBy。startIndex, offsetBy:2),因此修剪后的字符串将从索引2开始(即从第二个字符开始)和endIndex = -1 -> str.index(str. index)中的offsetBy。endIndex, offsetBy: -1),即从末尾开始修剪1个字符。

var str = "VEGANISM"
print (str[str.index(str.startIndex, offsetBy:0)..<str.index(str.endIndex, offsetBy: 0)] )

//Output-> VEGANISM

作为offsetBy值= 0两边,即str.index(str. index)。startIndex, offsetBy:0)和str.index(str. index)endIndex, offsetBy: 0)因此,将打印完整的字符串

谁曾经在Swift中负责字符串,这完全是一团糟,这绝对是该语言最糟糕的特性之一。

一个简单的解决方法是实现这样一个函数(或使它成为一个扩展函数):

func substring(str: String, start: Int, end : Int) -> String
{
    let startIndex = str.index(str.startIndex, offsetBy: start)
    let endIndex = str.index(str.startIndex, offsetBy: end)
    return String(str[startIndex..<endIndex])
}

在上面的基础上,我需要在非打印字符处分割字符串,删除非打印字符。我开发了两种方法:

var str = "abc\u{1A}12345sdf"
let range1: Range<String.Index> = str.range(of: "\u{1A}")!
let index1: Int = str.distance(from: str.startIndex, to: range1.lowerBound)
let start = str.index(str.startIndex, offsetBy: index1)
let end = str.index(str.endIndex, offsetBy: -0)
let result = str[start..<end] // The result is of type Substring
let firstStr = str[str.startIndex..<range1.lowerBound]

我用上面的一些答案组合在一起。

因为字符串是一个集合,然后我做了以下工作:

var fString = String()
for (n,c) in str.enumerated(){

*if c == "\u{1A}" {
    print(fString);
    let lString = str.dropFirst(n + 1)
    print(lString)
    break
   }
 fString += String(c)
}*

这对我来说更直观。哪个是最好的?我不知道 它们都使用Swift 5