我一直在更新我的一些旧代码和答案与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>)

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


当前回答

斯威夫特 4+

extension String {
    func take(_ n: Int) -> String {
        guard n >= 0 else {
            fatalError("n should never negative")
        }
        let index = self.index(self.startIndex, offsetBy: min(n, self.count))
        return String(self[..<index])
    }
}

返回前n个字符的子序列,如果字符串较短,则返回整个字符串。(灵感来源:https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/take.html)

例子:

let text = "Hello, World!"
let substring = text.take(5) //Hello

其他回答

谁曾经在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])
}

斯威夫特5 let desiredIndex: Int = 7 let substring = str[字符串]。指数(encodedOffset: desiredIndex)…] 这个子字符串变量会给你结果。 这里Int被转换为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 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"

同样的挫折,这应该不难…

我编译了这个从较大文本中获取子字符串位置的示例:

//
// Play with finding substrings returning an array of the non-unique words and positions in text
//
//

import UIKit

let Bigstring = "Why is it so hard to find substrings in Swift3"
let searchStrs : Array<String>? = ["Why", "substrings", "Swift3"]

FindSubString(inputStr: Bigstring, subStrings: searchStrs)


func FindSubString(inputStr : String, subStrings: Array<String>?) ->    Array<(String, Int, Int)> {
    var resultArray : Array<(String, Int, Int)> = []
    for i: Int in 0...(subStrings?.count)!-1 {
        if inputStr.contains((subStrings?[i])!) {
            let range: Range<String.Index> = inputStr.range(of: subStrings![i])!
            let lPos = inputStr.distance(from: inputStr.startIndex, to: range.lowerBound)
            let uPos = inputStr.distance(from: inputStr.startIndex, to: range.upperBound)
            let element = ((subStrings?[i])! as String, lPos, uPos)
            resultArray.append(element)
        }
    }
    for words in resultArray {
        print(words)
    }
    return resultArray
}

返回 ("Why" 0,3) ("substrings", 26, 36) (“Swift3”,40,46)