是时候承认失败了……

在Objective-C中,我可以使用如下内容:

NSString* str = @"abcdefghi";
[str rangeOfString:@"c"].location; // 2

在Swift中,我看到了类似的东西:

var str = "abcdefghi"
str.rangeOfString("c").startIndex

...但这只是给了我一个字符串。索引,我可以使用它下标回原始字符串,但不能从中提取位置。

FWIW,字符串。Index有一个名为_position的私有ivar,其中有正确的值。我只是不明白怎么会暴露出来。

我知道我自己可以很容易地将其添加到String中。我更好奇在这个新的API中我缺少了什么。


当前回答

最简单的方法是:

在Swift 3中:

 var textViewString:String = "HelloWorld2016"
    guard let index = textViewString.characters.index(of: "W") else { return }
    let mentionPosition = textViewString.distance(from: index, to: textViewString.endIndex)
    print(mentionPosition)

其他回答

我不确定如何从字符串中提取位置。索引,但如果你愿意回到一些Objective-C框架,你可以桥接到Objective-C,用和以前一样的方式。

"abcdefghi".bridgeToObjectiveC().rangeOfString("c").location

看起来有些NSString方法还没有(或者可能不会)移植到String中。包含也出现在脑海中。

Swift 4完整解决方案:

OffsetIndexableCollection(使用Int索引的字符串)

https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-

let a = "01234"

print(a[0]) // 0
print(a[0...4]) // 01234
print(a[...]) // 01234

print(a[..<2]) // 01
print(a[...2]) // 012
print(a[2...]) // 234
print(a[2...3]) // 23
print(a[2...2]) // 2

if let number = a.index(of: "1") {
    print(number) // 1
    print(a[number...]) // 1234
}

if let number = a.index(where: { $0 > "1" }) {
    print(number) // 2
}

斯威夫特5

查找子字符串的索引

let str = "abcdecd"
if let range: Range<String.Index> = str.range(of: "cd") {
    let index: Int = str.distance(from: str.startIndex, to: range.lowerBound)
    print("index: ", index) //index: 2
}
else {
    print("substring not found")
}

查找字符索引

let str = "abcdecd"
if let firstIndex = str.firstIndex(of: "c") {
    let index: Int = str.distance(from: str.startIndex, to: firstIndex)
    print("index: ", index)   //index: 2
}
else {
    print("symbol not found")
}

仔细想想,你其实并不需要位置的确切Int版本。范围甚至是字符串。如果需要,Index足以再次获取子字符串:

let myString = "hello"

let rangeOfE = myString.rangeOfString("e")

if let rangeOfE = rangeOfE {
    myString.substringWithRange(rangeOfE) // e
    myString[rangeOfE] // e

    // if you do want to create your own range
    // you can keep the index as a String.Index type
    let index = rangeOfE.startIndex
    myString.substringWithRange(Range<String.Index>(start: index, end: advance(index, 1))) // e

    // if you really really need the 
    // Int version of the index:
    let numericIndex = distance(index, advance(index, 1)) // 1 (type Int)
}

最简单的方法是:

在Swift 3中:

 var textViewString:String = "HelloWorld2016"
    guard let index = textViewString.characters.index(of: "W") else { return }
    let mentionPosition = textViewString.distance(from: index, to: textViewString.endIndex)
    print(mentionPosition)