Index of a substring in a string with Swift Index of a substring in a string with Swift swift swift

Index of a substring in a string with Swift


edit/update:

Xcode 11.4 • Swift 5.2 or later

import Foundationextension StringProtocol {    func index<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> Index? {        range(of: string, options: options)?.lowerBound    }    func endIndex<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> Index? {        range(of: string, options: options)?.upperBound    }    func indices<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> [Index] {        ranges(of: string, options: options).map(\.lowerBound)    }    func ranges<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> [Range<Index>] {        var result: [Range<Index>] = []        var startIndex = self.startIndex        while startIndex < endIndex,            let range = self[startIndex...]                .range(of: string, options: options) {                result.append(range)                startIndex = range.lowerBound < range.upperBound ? range.upperBound :                    index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex        }        return result    }}

usage:

let str = "abcde"if let index = str.index(of: "cd") {    let substring = str[..<index]   // ab    let string = String(substring)    print(string)  // "ab\n"}

let str = "Hello, playground, playground, playground"str.index(of: "play")      // 7str.endIndex(of: "play")   // 11str.indices(of: "play")    // [7, 19, 31]str.ranges(of: "play")     // [{lowerBound 7, upperBound 11}, {lowerBound 19, upperBound 23}, {lowerBound 31, upperBound 35}]

case insensitive sample

let query = "Play"let ranges = str.ranges(of: query, options: .caseInsensitive)let matches = ranges.map { str[$0] }   //print(matches)  // ["play", "play", "play"]

regular expression sample

let query = "play"let escapedQuery = NSRegularExpression.escapedPattern(for: query)let pattern = "\\b\(escapedQuery)\\w+"  // matches any word that starts with "play" prefixlet ranges = str.ranges(of: pattern, options: .regularExpression)let matches = ranges.map { str[$0] }print(matches) //  ["playground", "playground", "playground"]


Using String[Range<String.Index>] subscript you can get the sub string. You need starting index and last index to create the range and you can do it as below

let str = "abcde"if let range = str.range(of: "cd") {  let substring = str[..<range.lowerBound] // or str[str.startIndex..<range.lowerBound]  print(substring)  // Prints ab}else {  print("String not present")}

If you don't define the start index this operator ..< , it take the starting index. You can also use str[str.startIndex..<range.lowerBound] instead of str[..<range.lowerBound]


Swift 5

Find index of substring

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

Find index of Character

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