我还没有弄清楚如何在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))
想法吗?
Rob Napier已经用下标给出了一个很棒的答案。但我觉得有一个缺点,因为没有检查出约束条件。这可能会导致崩溃。所以我修改了扩展,在这里
extension String {
subscript (r: Range<Int>) -> String? { //Optional String as return value
get {
let stringCount = self.characters.count as Int
//Check for out of boundary condition
if (stringCount < r.endIndex) || (stringCount < r.startIndex){
return nil
}
let startIndex = self.startIndex.advancedBy(r.startIndex)
let endIndex = self.startIndex.advancedBy(r.endIndex - r.startIndex)
return self[Range(start: startIndex, end: endIndex)]
}
}
}
下面的输出
var str2 = "Hello, World"
var str3 = str2[0...5]
//Hello,
var str4 = str2[0..<5]
//Hello
var str5 = str2[0..<15]
//nil
所以我建议总是检查if let
if let string = str[0...5]
{
//Manipulate your string safely
}
您可以使用substringWithRange方法。它有一个开头和结尾String.Index。
var str = "Hello, playground"
str.substringWithRange(Range<String.Index>(start: str.startIndex, end: str.endIndex)) //"Hello, playground"
要更改开始和结束索引,请使用advancedBy(n)。
var str = "Hello, playground"
str.substringWithRange(Range<String.Index>(start: str.startIndex.advancedBy(2), end: str.endIndex.advancedBy(-1))) //"llo, playgroun"
你也可以用NSRange使用NSString方法,但你必须确保你使用的是这样的NSString:
let myNSString = str as NSString
myNSString.substringWithRange(NSRange(location: 0, length: 3))
注意:正如JanX2提到的,第二个方法对于unicode字符串是不安全的。
关于如何解决这个问题,已经有很多很好的例子。最初的问题是关于使用substringWithRange,但正如已经指出的那样,这比仅仅做自己的扩展更难。
上述范围的解决方案是很好的。你还可以用其他十几种方法来做到这一点。下面是另一个例子,告诉你如何做到这一点:
extension String{
func sub(start: Int, length: Int) -> String {
assert(start >= 0, "Cannot extract from a negative starting index")
assert(length >= 0, "Cannot extract a negative length string")
assert(start <= countElements(self) - 1, "cannot start beyond the end")
assert(start + length <= countElements(self), "substring goes past the end of the original")
var a = self.substringFromIndex(start)
var b = a.substringToIndex(length)
return b
}
}
var s = "apple12345"
println(s.sub(6, length: 4))
// prints "2345"
在操场上试试这个
var str:String = "Hello, playground"
let range = Range(start:advance(str.startIndex,1), end: advance(str.startIndex,8))
它会给出"ello, p"
然而,有趣的是,如果你使最后一个索引大于playground中的字符串,它将显示你在str:o之后定义的任何字符串
Range()似乎是一个泛型函数,因此它需要知道它正在处理的类型。
你还必须给它实际的字符串,你感兴趣的游乐场,因为它似乎持有所有的刺在一个接一个的序列与他们的变量名之后。
So
var str:String = "Hello, playground"
var str2:String = "I'm the next string"
let range = Range(start:advance(str.startIndex,1), end: advance(str.startIndex,49))
我是下一条线
即使str2使用let定义也有效
:)