3

I have 2 functions written in Swift 2, but Apple forced me to migrate to Swift 4 and I can't fix the functions.

extension String {
    func stringsMatchingRegularExpression(expression: String) -> [String] {
        if let range = self.rangeOfString(expression, options: NSString.CompareOptions.RegularExpressionSearch, range: nil, locale: nil) {
            return [self[range]] + self[range.endIndex..<self.endIndex].stringsMatchingRegularExpression(expression)
        }
        return []
    }

    func stringsMatchingRegularExpressionLarge(expression: String) -> [String] {
        var result = [String]()
        var currentRange = self.characters.indices
        while let range = self.rangeOfString(expression, options: NSString.CompareOptions.RegularExpressionSearch, range: currentRange, locale: nil) {
            result.append(self[range])
            currentRange.startIndex = range.endIndex
        }
        return result
    }
}

The return of the first function is the problem I can't fix it. The 3rd line is if let range = self.range(of: expression, options: NSString.CompareOptions.regularExpression, range: nil, locale: nil){ in Swift 4

In 2nd function I don't know how .characters migrating.

Mojtaba Hosseini
  • 71,072
  • 19
  • 226
  • 225
Bogdan Bogdanov
  • 1,182
  • 11
  • 35
  • 72

1 Answers1

3

.characters are gone. You can use the string itself directly.

Change self.characters.indices to self.indices

Change self.rangeOfString(expression, options: NSString.CompareOptions.RegularExpressionSearch, range: nil, locale: nil) to self.range(of: expression, options: .regularExpression, range: nil, locale: nil)

And lastly, you can use NSRegularExpression instead of recursively call the function, but note that it can throw some errors, so you should handle it somehow. Use this extension:

extension String {
    func stringsMatchingRegularExpression(expression regex: String) throws -> [String] {
        let regex = try NSRegularExpression(pattern: regex)
        let results = regex.matches(in: self,
                                    range: NSRange(self.startIndex..., in: self))
        return results.map {
            String(self[Range($0.range, in: self)!])
        }
    }
}

- More Swifty-Style:

extension String {

    func matching(expression regex: @autoclosure () throws -> NSRegularExpression) rethrows -> [String] {
        let results = try regex().matches(in: self, range: NSRange(self.startIndex..., in: self))
        return results.map {
            String(self[Range($0.range, in: self)!])
        }
    }

    func matching(pattern regexPattern: String) throws -> [String] {
        return try self.matching(expression: NSRegularExpression(pattern: regexPattern))
    }
}
Mojtaba Hosseini
  • 71,072
  • 19
  • 226
  • 225