我一直在更新我的一些旧代码和答案与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
在swift 4字符串符合集合。现在应该使用下标,而不是substring。所以如果你只想从“Hello, playground”中删除单词“play”,你可以这样做:
var str = "Hello, playground"
let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let result = str[start..<end] // The result is of type Substring
有趣的是,这样做会给你一个Substring而不是String。这是快速和有效的,因为Substring与原始字符串共享其存储空间。然而,以这种方式共享内存也很容易导致内存泄漏。
这就是为什么一旦您想要清理原始的String,就应该将结果复制到一个新的String中。你可以使用普通的构造函数:
let newString = String(result)
你可以在[Apple文档].1中找到更多关于新的Substring类的信息
所以,如果你得到一个范围作为nsregularexexpression的结果,你可以使用以下扩展:
extension String {
subscript(_ range: NSRange) -> String {
let start = self.index(self.startIndex, offsetBy: range.lowerBound)
let end = self.index(self.startIndex, offsetBy: range.upperBound)
let subString = self[start..<end]
return String(subString)
}
}
斯威夫特4
在swift 4字符串符合集合。现在应该使用下标,而不是substring。所以如果你只想从“Hello, playground”中删除单词“play”,你可以这样做:
var str = "Hello, playground"
let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let result = str[start..<end] // The result is of type Substring
有趣的是,这样做会给你一个Substring而不是String。这是快速和有效的,因为Substring与原始字符串共享其存储空间。然而,以这种方式共享内存也很容易导致内存泄漏。
这就是为什么一旦您想要清理原始的String,就应该将结果复制到一个新的String中。你可以使用普通的构造函数:
let newString = String(result)
你可以在[Apple文档].1中找到更多关于新的Substring类的信息
所以,如果你得到一个范围作为nsregularexexpression的结果,你可以使用以下扩展:
extension String {
subscript(_ range: NSRange) -> String {
let start = self.index(self.startIndex, offsetBy: range.lowerBound)
let end = self.index(self.startIndex, offsetBy: range.upperBound)
let subString = self[start..<end]
return String(subString)
}
}
同样的挫折,这应该不难…
我编译了这个从较大文本中获取子字符串位置的示例:
//
// 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)
下面是一个函数,当提供了开始和结束索引时,返回给定子字符串的子字符串。如需完整参考资料,请浏览以下连结。
func substring(string: String, fromIndex: Int, toIndex: Int) -> String? {
if fromIndex < toIndex && toIndex < string.count /*use string.characters.count for swift3*/{
let startIndex = string.index(string.startIndex, offsetBy: fromIndex)
let endIndex = string.index(string.startIndex, offsetBy: toIndex)
return String(string[startIndex..<endIndex])
}else{
return nil
}
}
这是我为处理swift中的字符串操作而创建的博客文章的链接。
swift中的字符串操作(也包括swift 4)
或者你可以在github上看到这个要点
下面是一个更通用的实现:
这种技术仍然使用索引来保持Swift的标准,并暗示一个完整的字符。
extension String
{
func subString <R> (_ range: R) -> String? where R : RangeExpression, String.Index == R.Bound
{
return String(self[range])
}
func index(at: Int) -> Index
{
return self.index(self.startIndex, offsetBy: at)
}
}
从第3个字符开始子字符串:
let item = "Fred looks funny"
item.subString(item.index(at: 2)...) // "ed looks funny"
我已经使用驼峰subString表示它返回一个字符串,而不是一个subString。