我还没有弄清楚如何在Swift中获得字符串的子字符串:
var str = “Hello, playground”
func test(str: String) -> String {
return str.substringWithRange( /* What goes here? */ )
}
test (str)
我不能在Swift中创建一个范围。自动完成在游乐场不是超级有用的-这是它的建议:
return str.substringWithRange(aRange: Range<String.Index>)
我在Swift标准参考库中没有找到任何有用的东西。下面是另一个大胆的猜测:
return str.substringWithRange(Range(0, 1))
这:
let r:Range<String.Index> = Range<String.Index>(start: 0, end: 2)
return str.substringWithRange(r)
我看到了其他答案(在Swift字符串中查找字符索引),似乎表明,由于字符串是NSString的桥类型,“旧”方法应该工作,但不清楚如何-例如,这也不工作(似乎不是有效的语法):
let x = str.substringWithRange(NSMakeRange(0, 3))
想法吗?
注意:@airspeedswift对这种方法的权衡提出了一些非常深刻的观点,特别是隐藏的性能影响。字符串不是简单的野兽,获得特定的索引可能需要O(n)时间,这意味着使用下标的循环可能是O(n²)。我警告过你了。
你只需要添加一个新的下标函数,它接受一个范围,并使用advancedBy()走到你想要的地方:
import Foundation
extension String {
subscript (r: Range<Int>) -> String {
get {
let startIndex = self.startIndex.advancedBy(r.startIndex)
let endIndex = startIndex.advancedBy(r.endIndex - r.startIndex)
return self[Range(start: startIndex, end: endIndex)]
}
}
}
var s = "Hello, playground"
println(s[0...5]) // ==> "Hello,"
println(s[0..<5]) // ==> "Hello"
(这绝对应该是语言的一部分。请dupe rdar://17158813)
为了好玩,你还可以在索引上添加一个+运算符:
func +<T: ForwardIndex>(var index: T, var count: Int) -> T {
for (; count > 0; --count) {
index = index.succ()
}
return index
}
s.substringWithRange(s.startIndex+2 .. s.startIndex+5)
(我还不知道这个是否应该成为语言的一部分。)
借鉴Rob Napier的经验,我开发了这些常见的字符串扩展,其中两个是:
subscript (r: Range<Int>) -> String
{
get {
let startIndex = advance(self.startIndex, r.startIndex)
let endIndex = advance(self.startIndex, r.endIndex - 1)
return self[Range(start: startIndex, end: endIndex)]
}
}
func subString(startIndex: Int, length: Int) -> String
{
var start = advance(self.startIndex, startIndex)
var end = advance(self.startIndex, startIndex + length)
return self.substringWithRange(Range<String.Index>(start: start, end: end))
}
用法:
"Awesome"[3...7] //"some"
"Awesome".subString(3, length: 4) //"some"
例如,在我的全名中查找第一个名字(直到第一个空格):
let name = "Joris Kluivers"
let start = name.startIndex
let end = find(name, " ")
if end {
let firstName = name[start..end!]
} else {
// no space found
}
start和end是String类型。索引和用于创建Range<String。索引>并用于下标访问器(如果在原始字符串中找到空格)。
很难创建一个字符串。直接从一个整数位置索引,就像在开头帖子中使用的那样。这是因为在我的名字中,每个字符的字节大小都是相等的。但是在其他语言中使用特殊重音的字符可能会使用更多的字节(取决于所使用的编码)。那么这个整数应该指向哪个字节呢?
可以创建一个新的String。使用succ和pred方法从现有的代码中索引,这将确保跳过正确的字节数以到达编码中的下一个代码点。然而,在这种情况下,更容易搜索字符串中第一个空格的索引来找到结束索引。