String 在Swift字符串中查找字符索引

String 在Swift字符串中查找字符索引,string,swift,String,Swift,是时候承认失败了 在Objective-C中,我可以使用如下内容: NSString* str = @"abcdefghi"; [str rangeOfString:@"c"].location; // 2 在Swift中,我看到了类似的情况: var str = "abcdefghi" str.rangeOfString("c").startIndex …但这只会给我一个字符串.Index,我可以用它下标回原始字符串,但不能从中提取位置 FWIW,即String.Index有一个名为\u

是时候承认失败了

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

NSString* str = @"abcdefghi";
[str rangeOfString:@"c"].location; // 2
在Swift中,我看到了类似的情况:

var str = "abcdefghi"
str.rangeOfString("c").startIndex
…但这只会给我一个
字符串.Index
,我可以用它下标回原始字符串,但不能从中提取位置

FWIW,即
String.Index
有一个名为
\u position
的私有ivar,其中包含正确的值。我只是不知道它是怎么暴露出来的


我知道我可以很容易地把这个添加到字符串中。我对这个新API中缺少的东西更感好奇。

如果您想使用熟悉的NSString,可以显式声明它:

var someString: NSString = "abcdefghi"

var someRange: NSRange = someString.rangeOfString("c")

我还不确定如何在Swift中实现这一点。

我不确定如何从String.Index中提取位置,但如果您愿意依赖于某些Objective-C框架,您可以连接到Objective-C,并按照以前的方式进行操作

"abcdefghi".bridgeToObjectiveC().rangeOfString("c").location
似乎有些NSString方法还没有(或者可能不会)移植到String。我也想到了包含。

这对我来说很有效

var loc = "abcdefghi".rangeOfString("c").location
NSLog("%d", loc);
这也行得通

var myRange: NSRange = "abcdefghi".rangeOfString("c")
var loc = myRange.location
NSLog("%d", loc);

String是NSString的桥接类型,因此添加

import Cocoa

使用所有“旧”方法创建swift文件。

你不是唯一一个找不到解决方案的人

String
未实现
RandomAccessIndexType
。可能是因为它们启用了不同字节长度的字符。这就是为什么我们必须使用
string.characters.count
(Swift 1.x中的
count
countElements
)来获取字符数。这也适用于职位。
\u位置
可能是原始字节数组的索引,他们不想公开它。<代码>字符串。index <代码>是为了保护我们不访问字符中间的字节。

这意味着您必须从
String.startIndex
String.endIndex
String.index
实现
BidirectionalIndexType
)创建任何索引。可以使用
后续
前置
方法创建任何其他索引

现在,为了帮助我们使用索引,有一组方法(Swift 1.x中的函数):

Swift 4.x

使用
String.Index
很麻烦,但使用包装器按整数进行索引(请参阅)是危险的,因为它隐藏了实际索引的低效性

请注意,Swift索引实现存在一个问题,即为一个字符串创建的索引/范围不能可靠地用于另一个字符串,例如:

Swift 2.x

let text:String=“abc”
让text2:String=“
扩展字符串{
var str = "abcdefghi" as NSString
str.rangeOfString("c").locationx   // returns 2
//标记:-子字符串 func substringToIndex(索引:Int)->字符串{ 返回self.substringToIndex(advance(self.startIndex,index)) } func substringFromIndex(索引:Int)->字符串{ 返回self.substringFromIndex(advance(self.startIndex,index)) } func substringWithRange(范围:range)->String{ 让开始=前进(self.startIndex,range.startIndex) 让结束=前进(self.startIndex,range.endIndex) 返回self.substringWithRange(开始..字符{ 返回self[前进(self.startIndex,索引)] } 下标(范围:范围)->字符串{ 让开始=前进(self.startIndex,range.startIndex) 让结束=前进(self.startIndex,range.endIndex) 返回self[start..String{ 变量结果:NSMutableString=NSMutableString(字符串:self) 结果.replaceCharactersRange(NSRange(range),带字符串:带字符串) 返回结果 } }
如果您正在寻找获取字符或字符串索引的简单方法,请签出此库


您也可以使用另一个字符串或正则表达式模式从字符串中获取索引。Swift中的变量类型字符串与Objective-C中的NSString包含不同的函数。正如Sulthan所述

Swift字符串不实现RandomAccessIndex

您可以将字符串类型的变量向下转换为NSString(这在Swift中有效)。这将使您能够访问NSString中的函数

let string = "Hello.World"
let needle: Character = "."
if let idx = string.characters.index(of: needle) {
    let pos = string.characters.distance(from: string.startIndex, to: idx)
    print("Found \(needle) at position \(pos)")
}
else {
    print("Not found")
}

Swift 3.0使其更加冗长:

extension String {
    public func index(of char: Character) -> Int? {
        if let idx = characters.index(of: char) {
            return characters.distance(from: startIndex, to: idx)
        }
        return nil
    }
}
分机:

let string = "Hello.World"
let needle: Character = "."
if let idx = string.characters.indexOf(needle) {
    let pos = string.startIndex.distanceTo(idx)
    print("Found \(needle) at position \(pos)")
}
else {
    print("Not found")
}
let string = "Hello.World"
let needle: Character = "."
if let idx = find(string, needle) {
    let pos = distance(string.startIndex, idx)
    println("Found \(needle) at position \(pos)")
}
else {
    println("Not found")
}


Swift 2.0中这变得更容易:

extension String {
    public func indexOfCharacter(char: Character) -> Int? {
        if let idx = self.characters.indexOf(char) {
            return self.startIndex.distanceTo(idx)
        }
        return nil
    }
}
分机:

let string = "Hello.World"
let needle: Character = "."
if let idx = string.characters.indexOf(needle) {
    let pos = string.startIndex.distanceTo(idx)
    print("Found \(needle) at position \(pos)")
}
else {
    print("Not found")
}
let string = "Hello.World"
let needle: Character = "."
if let idx = find(string, needle) {
    let pos = distance(string.startIndex, idx)
    println("Found \(needle) at position \(pos)")
}
else {
    println("Not found")
}

Swift 1.x实施:

对于纯Swift解决方案,可以使用:

extension String {
    public func indexOfCharacter(char: Character) -> Int? {
        if let idx = find(self, char) {
            return distance(self.startIndex, idx)
        }
        return nil
    }
}
作为
字符串
的扩展:

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

仔细想想,实际上并不需要精确的Int版本的位置。如果需要,范围甚至字符串.Index足以再次取出子字符串:

var str : String = "abcdefghi"
let characterToFind: Character = "c"
let characterIndex = find(str, characterToFind)  //returns 2
让myString=“你好”
设rangeOfE=myString.rangeOfString(“e”)
如果让rangeOfE=rangeOfE{
myString.substringWithRange(rangeOfE)//e
myString[rangeOfE]/e
//如果要创建自己的范围
//可以将索引保留为字符串。索引类型
让索引=rangeOfE.startIndex
myString.substringWithRange(范围(开始:索引,结束:高级(索引,1))//e
//如果你真的需要
//索引的Int版本:
设numericIndex=distance(index,advance(index,1))//1(type Int)
}

我知道这是一个古老的问题,答案已经被接受,但您可以使用以下方法在几行代码中找到字符串的索引:

var str = "abcdefghi"
let indexForCharacterInString = str.characters.indexOf("c") //returns 2

这里还有一些关于Swift字符串的重要信息

我找到了swift2的解决方案:

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

下面是一个干净的字符串扩展,它回答了这个问题:

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

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
    }
}
let text = "abc"
if let range = text.rangeOfString("b") {
   var index: Int = text.startIndex.distanceTo(range.startIndex) 
   ...
}
Swift 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
    }
}
let text = "abc"
if let range = text.rangeOfString("b") {
   var index: Int = text.startIndex.distanceTo(range.startIndex) 
   ...
}

要使用Swift 2获取字符串中子字符串的索引,请执行以下操作:

var stringMe="Something In this.World"
var needle="."
if let idx = stringMe.characters.indexOf(needle) {
    let pos=stringMe.substringFromIndex(idx)
    print("Found \(needle) at position \(pos)")
}
else {
    print("Not found")
}
在swift 2.0中

func substring(before sub: String) -> String {
    if let range = self.rangeOfString(sub),
        let index: Int = self.startIndex.distanceTo(range.startIndex) {
        return sub_range(0, index)
    }
    return ""
}

在Swift 2.0中,以下函数返回给定字符前的子字符串

let mystring:String = "indeep";
let findCharacter:Character = "d";

if (mystring.characters.contains(findCharacter))
{
    let position = mystring.characters.indexOf(findCharacter);
    NSLog("Position of c is \(mystring.startIndex.distanceTo(position!))")

}
else
{
    NSLog("Position of c is not found");
}

从思维角度来说,这可能被称为反转。你发现世界是圆的而不是平的。“你不需要知道字符的索引来处理它。”作为一名C程序员,我发现h
    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
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!)
extension String {
    func allCharactes() -> [Character] {
         var result: [Character] = []
         for c in self.characters {
             result.append(c)
         }
         return 
    }
}
let c = Array(str.characters)
let index = string.characters.index(of: ".")
let intIndex = string.distance(from: string.startIndex, to: index)
 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)
let loc = newString.range(of: ".").location
public extension Int {
    /// Creates an `Int` from a given index in a given string
    ///
    /// - Parameters:
    ///    - index:  The index to convert to an `Int`
    ///    - string: The string from which `index` came
    init(_ index: String.Index, in string: String) {
        self.init(string.distance(from: string.startIndex, to: index))
    }
}
var testString = "abcdefg"

Int(testString.range(of: "c")!.lowerBound, in: testString)     // 2

testString = "Swift 5.0

public extension String {  
  func indexInt(of char: Character) -> Int? {
    return firstIndex(of: char)?.utf16Offset(in: self)
  }
}
public extension String {  
  func indexInt(of char: Character) -> Int? {
    return index(of: char)?.encodedOffset        
  }
}
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
}
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
    }
  }

}
"apple".indexes(of: "p") // [1, 2]
"element".indexes(of: "e") // [0, 2, 4]
"swift".indexes(of: "j") // []
//Fucntion to get the index of a particular string
func index(of target: String) -> Int? {
    if let range = self.range(of: target) {
        return characters.distance(from: startIndex, to: range.lowerBound)
    } else {
        return nil
    }
}
//Fucntion to get the last index of occurence of a given string
func lastIndex(of target: String) -> Int? {
    if let range = self.range(of: target, options: .backwards) {
        return characters.distance(from: startIndex, to: range.lowerBound)
    } else {
        return nil
    }
}
var str = "abcdefghi"
if let index = str.firstIndex(of: "c") {
    let distance = str.distance(from: str.startIndex, to: index)
    // distance is 2
}
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")
}
 let testStr: String = "I love my family if you Love us to tell us I'm with you"
 var newStr = ""
 let char:Character = "i"

 for value in testStr {
      if value == char {
         newStr = newStr + String(value)
   }

}
print(newStr.count)