是时候承认失败了……

在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 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
}

其他回答

下面是一个干净的String扩展,回答了这个问题:

斯威夫特3:

extension String {
    var length:Int {
        return self.characters.count
    }

    func indexOf(target: String) -> Int? {

        let range = (self as NSString).range(of: target)

        guard range.toRange() != nil else {
            return nil
        }

        return range.location

    }
    func lastIndexOf(target: String) -> Int? {



        let range = (self as NSString).range(of: target, options: NSString.CompareOptions.backwards)

        guard range.toRange() != nil else {
            return nil
        }

        return self.length - range.location - 1

    }
    func contains(s: String) -> Bool {
        return (self.range(of: s) != nil) ? true : false
    }
}

斯威夫特2.2:

extension String {    
    var length:Int {
        return self.characters.count
    }

    func indexOf(target: String) -> Int? {

        let range = (self as NSString).rangeOfString(target)

        guard range.toRange() != nil else {
            return nil
        }

        return range.location

    }
    func lastIndexOf(target: String) -> Int? {



        let range = (self as NSString).rangeOfString(target, options: NSStringCompareOptions.BackwardsSearch)

        guard range.toRange() != nil else {
            return nil
        }

        return self.length - range.location - 1

    }
    func contains(s: String) -> Bool {
        return (self.rangeOfString(s) != nil) ? true : false
    }
}

与Objective-C中的NSString相比,Swift中的变量类型String包含不同的函数。Sulthan提到过,

Swift String没有实现RandomAccessIndex

你能做的是向下转换你的变量类型String到NSString(这是有效的Swift)。这将给你访问NSString中的函数。

var str = "abcdefghi" as NSString
str.rangeOfString("c").locationx   // returns 2

我玩以下的游戏

extension String {
    func allCharactes() -> [Character] {
         var result: [Character] = []
         for c in self.characters {
             result.append(c)
         }
         return 
    }
}

直到我理解提供的一个,现在它只是字符数组

let c = Array(str.characters)

在Swift 2中获取子字符串的索引:

let text = "abc"
if let range = text.rangeOfString("b") {
   var index: Int = text.startIndex.distanceTo(range.startIndex) 
   ...
}

如果您正在寻找简单的方法来获得字符或字符串的索引,请检查这个库http://www.dollarswift.org/#indexof-char-character-int

您也可以使用另一个字符串或正则表达式模式从字符串中获取indexOf