Index of a substring in a string with Swift

前端 未结 11 1647
自闭症患者
自闭症患者 2020-11-22 14:24

I\'m used to do this in JavaScript:

var domains = \"abcde\".substring(0, \"abcde\".indexOf(\"cd\")) // Returns \"ab\"

Swift doesn\'t have t

11条回答
  •  野性不改
    2020-11-22 15:08

    edit/update:

    Xcode 11.4 • Swift 5.2 or later

    import Foundation
    
    extension StringProtocol {
        func index(of string: S, options: String.CompareOptions = []) -> Index? {
            range(of: string, options: options)?.lowerBound
        }
        func endIndex(of string: S, options: String.CompareOptions = []) -> Index? {
            range(of: string, options: options)?.upperBound
        }
        func indices(of string: S, options: String.CompareOptions = []) -> [Index] {
            ranges(of: string, options: options).map(\.lowerBound)
        }
        func ranges(of string: S, options: String.CompareOptions = []) -> [Range] {
            var result: [Range] = []
            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[..

    let str = "Hello, playground, playground, playground"
    str.index(of: "play")      // 7
    str.endIndex(of: "play")   // 11
    str.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" prefix
    
    let ranges = str.ranges(of: pattern, options: .regularExpression)
    let matches = ranges.map { str[$0] }
    
    print(matches) //  ["playground", "playground", "playground"]
    

提交回复
热议问题