Строковое расширение для сопоставления с регулярным выражением

У меня есть 2 функции, написанные на Swift 2, но Apple заставила меня перейти на Swift 4, и я не могу исправить эти функции.

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

Возврат первой функции - это проблема, которую я не могу исправить. 3-я строка if let range = self.range(of: expression, options: NSString.CompareOptions.regularExpression, range: nil, locale: nil){ в Swift 4

Во второй функции я не знаю, как мигрируют .characters.


person Bogdan Bogdanov    schedule 22.06.2019    source источник
comment
Возможно полезно: stackoverflow.com/questions/27880650/   -  person Martin R    schedule 22.06.2019


Ответы (1)


.characters ушли. Вы можете использовать саму строку напрямую.

Изменить self.characters.indices на self.indices

Изменить self.rangeOfString(expression, options: NSString.CompareOptions.RegularExpressionSearch, range: nil, locale: nil) на self.range(of: expression, options: .regularExpression, range: nil, locale: nil)

И, наконец, вы можете использовать NSRegularExpression вместо рекурсивного вызова функции, но обратите внимание, что это может throw привести к некоторым ошибкам, поэтому вы должны как-то с этим справиться. Используйте это расширение:

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

- Более быстрый стиль:

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))
    }
}
person Mojtaba Hosseini    schedule 22.06.2019
comment
Как насчет большого выражения? - person Bogdan Bogdanov; 22.06.2019
comment
Я считаю, что это может справиться с обоими. - person Mojtaba Hosseini; 22.06.2019
comment
Я добавил еще несколько удобных кодов. проверьте это, если хотите. - person Mojtaba Hosseini; 22.06.2019