WildCat's Blog

Swift 中如何缩短 Range<String.Index> 的长度

今天写一个小项目的时候遇到一个这样的需求,截取一个类似 Michael: Hello, World! 的字符串中的名字部分,当然,代码如下:

// Note: You have to import Foundation in Playground  
let rawString = "Michael: Hello, World!"  
let range = rawString.rangeOfString("^\\w{0,10}:", options: .RegularExpressionSearch)  

if (range != nil) {  
    println(rawString.substringWithRange(range!))  
}  
// Output:  
// Michael:  

那么,这个 range 的长度如何减少1呢?
这里的 range 的类型是 Range<String.Index> ,它无法直接减1,下面的做法是错误的:

 
range! - 1  
range!.endIndex - 1  
不过, Range<SomeTypes>.startIndex 或者 Range<SomeTypes>.endIndexpredecessor()successor() 方法,分别为 向前 和 向后一位。这样,我们的需求就可以实现了:
if (range != nil) {  
    let subRange = Range<String.Index>(start: range!.startIndex, end: range!.endIndex.predecessor())  
    // 这一行可以简写为:  
    let subRange2 = range!.startIndex ..< range!.endIndex.predecessor()  
    println(rawString!.substringWithRange(subRange))  
}  
// Output:  
// Michael  

每次都需要调用 predecessor()successor() 挺麻烦,但是这种需求可以通过重载操作符实现类似 range!.endIndex - 1 的效果,这个坑等以后再填吧。

附: http://stackoverflow.com/questions/24044851/how-do-you-use-string-substringwithrange-or-how-do-ranges-work-in-swift