是时候承认失败了……

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

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

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

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

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

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

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


当前回答

extension String {

    // MARK: - sub String
    func substringToIndex(index:Int) -> String {
        return self.substringToIndex(advance(self.startIndex, index))
    }
    func substringFromIndex(index:Int) -> String {
        return self.substringFromIndex(advance(self.startIndex, index))
    }
    func substringWithRange(range:Range<Int>) -> String {
        let start = advance(self.startIndex, range.startIndex)
        let end = advance(self.startIndex, range.endIndex)
        return self.substringWithRange(start..<end)
    }

    subscript(index:Int) -> Character{
        return self[advance(self.startIndex, index)]
    }
    subscript(range:Range<Int>) -> String {
        let start = advance(self.startIndex, range.startIndex)
            let end = advance(self.startIndex, range.endIndex)
            return self[start..<end]
    }


    // MARK: - replace
    func replaceCharactersInRange(range:Range<Int>, withString: String!) -> String {
        var result:NSMutableString = NSMutableString(string: self)
        result.replaceCharactersInRange(NSRange(range), withString: withString)
        return result
    }
}

其他回答

在思考方面,这可能被称为反转。你会发现世界是圆的而不是平的。“你真的不需要知道角色的索引来处理它。”作为一名C程序员,我发现这也很难接受! 你的行“let index = letters.characters.indexOf("c")!”本身就足够了。 例如,要去掉c,你可以用…(操场粘贴)

    var letters = "abcdefg"
  //let index = letters.rangeOfString("c")!.startIndex //is the same as
    let index = letters.characters.indexOf("c")!
    range = letters.characters.indexOf("c")!...letters.characters.indexOf("c")!
    letters.removeRange(range)
    letters

然而,如果你想要一个索引,你需要返回一个实际的index而不是Int值,因为Int值对于任何实际使用都需要额外的步骤。这些扩展返回一个索引,一个特定字符的计数,以及这个游乐场插件代码将演示的范围。

extension String
{
    public func firstIndexOfCharacter(aCharacter: Character) -> String.CharacterView.Index? {

        for index in self.characters.indices {
            if self[index] == aCharacter {
                return index
            }

        }
        return nil
    }

    public func returnCountOfThisCharacterInString(aCharacter: Character) -> Int? {

        var count = 0
        for letters in self.characters{

            if aCharacter == letters{

                count++
            }
        }
        return count
    }


    public func rangeToCharacterFromStart(aCharacter: Character) -> Range<Index>? {

        for index in self.characters.indices {
            if self[index] == aCharacter {
                let range = self.startIndex...index
                return range
            }

        }
        return nil
    }

}



var MyLittleString = "MyVery:important String"

var theIndex = MyLittleString.firstIndexOfCharacter(":")

var countOfColons = MyLittleString.returnCountOfThisCharacterInString(":")

var theCharacterAtIndex:Character = MyLittleString[theIndex!]

var theRange = MyLittleString.rangeToCharacterFromStart(":")
MyLittleString.removeRange(theRange!)

如果你只需要一个字符的索引,最简单,快速的解决方案(正如Pascal已经指出的那样)是:

let index = string.characters.index(of: ".")
let intIndex = string.distance(from: string.startIndex, to: index)

你也可以像这样在一个字符串中找到一个字符的索引,

extension String {

  func indexes(of character: String) -> [Int] {

    precondition(character.count == 1, "Must be single character")

    return self.enumerated().reduce([]) { partial, element  in
      if String(element.element) == character {
        return partial + [element.offset]
      }
      return partial
    }
  }

}

它在[String]中给出结果。距离ie。(Int)

"apple".indexes(of: "p") // [1, 2]
"element".indexes(of: "e") // [0, 2, 4]
"swift".indexes(of: "j") // []

斯威夫特5.0

public extension String {  
  func indexInt(of char: Character) -> Int? {
    return firstIndex(of: char)?.utf16Offset(in: self)
  }
}

斯威夫特4.0

public extension String {  
  func indexInt(of char: Character) -> Int? {
    return index(of: char)?.encodedOffset        
  }
}

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

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

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