Swift 5.1 Regex Bug - PullRequest
       0

Swift 5.1 Regex Bug

0 голосов
/ 08 февраля 2020

для следующего кода:

import Foundation

extension String {
    var fullRange: NSRange {
        return .init(self.startIndex ..< self.endIndex, in: self)
    }
    public subscript(range: Range<Int>) -> Self.SubSequence {
        let st = self.index(self.startIndex, offsetBy: range.startIndex)
        let ed = self.index(self.startIndex, offsetBy: range.endIndex)
        let sub = self[st ..< ed]
        return sub
    }

    func split(regex pattern: String) throws -> [String] {
        let regex = try NSRegularExpression.init(pattern: pattern, options: [])
        let fRange = self.fullRange
        let match = regex.matches(in: self, options: [], range: fRange)

        var list = [String]()
        var start = 0
        for m in match {
            let r = m.range
            let end = r.location

            list.append(String(self[start ..< end]))
            start = end + r.length
        }
        if start < self.count {
            list.append(String(self[start ..< self.count]))
        }
        return list
    }
}

print(try! "مرتفع جداً\nVery High".split(regex: "\n"))

вывод должен быть:

["مرتفع جداً", "Very High"]

, но вместо этого:

["مرتفع جداً\n", "ery High"]

, потому что регулярное выражение (для в данном случае) соответствует \n по смещению 10 вместо 9

в моем коде что-то не так, или это ошибка в swift с регулярным выражением !!

Ответы [ 2 ]

2 голосов
/ 09 февраля 2020

Это не ошибка. Вы пытаетесь использовать Int индексы, которые подвержены ошибкам и не рекомендуется в среде Unicode.

Это эквивалент вашего кода с правильным типом String.Index и выделенным API для преобразования NSRange до Range<String.Index> и наоборот. fullRange и subscript устарели.

Я только что пропустил строку печати. startIndex и endIndex являются свойствами String

extension String {
    func split(regex pattern: String) throws -> [String] {
        let regex = try NSRegularExpression(pattern: pattern)
        let matches = regex.matches(in: self, range: NSRange(startIndex..., in: self))

        var list = [String]()
        var start = startIndex
        for match in matches {

            let range = Range(match.range, in: self)!
            let end = range.lowerBound

            list.append(String(self[start..<end]))
            start = range.upperBound
        }
        if start < endIndex {
            list.append(String(self[start..<endIndex]))
        }

        return list
    }
}

print(try! "مرتفع جداً\nVery High".split(regex: "\n"))

Результат - ["مرتفع جداً", "Very High"]

0 голосов
/ 08 февраля 2020

Я обнаружил проблему, стоящую за этим bug?! Строки Swift намного более странные, чем любой другой язык; так как каждый символ имеет длину 4 байта, то один символ (может, будет, будет, ..) содержит 1 или 2 символа Unicode (что и случилось в моем случае), поэтому решение состоит в том, чтобы вместо этого поднастроить unicodeScalars быстрой строки Сама строка !!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...