我还没有弄清楚如何在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的经验,我开发了这些常见的字符串扩展,其中两个是:

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"

其他回答

由于String是NSString的桥接类型,“旧的”方法应该可以工作,但不清楚如何工作-例如,这也不起作用(似乎不是有效的语法): let x = str.substringWithRange(NSMakeRange(0,3))

对我来说,这是你问题中真正有趣的部分。String被桥接到NSString,所以大多数NSString方法直接作用于String。你可以自由地使用它们,不需要思考。例如,这正如你所期望的那样:

// delete all spaces from Swift String stateName
stateName = stateName.stringByReplacingOccurrencesOfString(" ", withString:"")

But, as so often happens, "I got my mojo workin' but it just don't work on you." You just happened to pick one of the rare cases where a parallel identically named Swift method exists, and in a case like that, the Swift method overshadows the Objective-C method. Thus, when you say str.substringWithRange, Swift thinks you mean the Swift method rather than the NSString method — and then you are hosed, because the Swift method expects a Range<String.Index>, and you don't know how to make one of those.

最简单的办法就是阻止霉霉这样做,明确地说:

let x = (str as NSString).substringWithRange(NSMakeRange(0, 3))

注意,这里没有涉及到重大的额外工作。“转换”并不意味着“转换”;String实际上是一个NSString。我们只是告诉Swift为了这一行代码的目的如何看待这个变量。

整个事情中真正奇怪的部分是导致所有这些麻烦的Swift方法是没有记录的。我不知道它的定义是什么;它不在NSString头文件中也不在Swift头文件中。

你可以在我写的Swift String扩展https://bit.ly/JString中使用任何子字符串方法。

var string = "hello"
var sub = string.substringFrom(3) // or string[3...5]
println(sub)// "lo"

在新的Xcode 7.0中使用

//: Playground - noun: a place where people can play

import UIKit

var name = "How do you use String.substringWithRange?"
let range = name.startIndex.advancedBy(0)..<name.startIndex.advancedBy(10)
name.substringWithRange(range)

//OUT:

如何在Swift 2.0中获取子字符串的示例代码

(i)起始索引的子字符串

输入:-

var str = "Swift is very powerful language!"
print(str)

str = str.substringToIndex(str.startIndex.advancedBy(5))
print(str)

输出:

Swift is very powerful language!
Swift

(ii)特定索引的子字符串

输入:-

var str = "Swift is very powerful language!"
print(str)

str = str.substringFromIndex(str.startIndex.advancedBy(6)).substringToIndex(str.startIndex.advancedBy(2))
print(str)

输出:

Swift is very powerful language!
is

希望对你有所帮助!

关于如何解决这个问题,已经有很多很好的例子。最初的问题是关于使用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"