Найдите NSRanges всех подстрок, разделенных новыми строками - PullRequest
0 голосов
/ 28 мая 2020

Итак, у меня есть этот код, который находит подстроки Range s путем разделения новых строк:

let string = "hello\nhello"
let rangesSplittedByLines: [Range] = string.split(separator: "\n").compactMap {
    return string.range(of: $0)
}

Но мне нужны эти диапазоны как NSRange. Как получить массив NSRange всех подстрок?

Ответы [ 2 ]

3 голосов
/ 28 мая 2020

Вместо разделения строки и «реконструкции» диапазонов вы можете использовать сопоставление регулярных выражений, которое возвращает диапазоны напрямую. Шаблон [^\n]+ соответствует одному или нескольким символам, которые не являются символом новой строки. Пример:

let string = "hello\nhello"

let regex = try! NSRegularExpression(pattern: #"[^\n]+"#)
let matches = regex.matches(in: string, range: NSRange(string.startIndex..., in: string))
let ranges = matches.map { $0.range }

print(ranges) // [{0, 5}, {6, 5}
2 голосов
/ 28 мая 2020

В закрытии создайте NSRange из Range<String.Index>

let string = "hello\nhello"
let rangesSplittedByLines: [NSRange] = string.split(separator: "\n").map {
    return NSRange(string.range(of: $0)!, in: string)
}

Но есть еще одна проблема. Код возвращает [{0, 5}, {0, 5}], потому что range(of: всегда возвращает диапазон первого совпадения.

Это устраняет проблему, он разрезает строку, перемещая начальный индекс в позицию после последнее совпадение

let string = "hello\nhello"
var startIndex = string.startIndex
let rangesSplittedByLines: [NSRange] = string.split(separator: "\n").map {
    let subString = string[startIndex...]
    let swiftRange = subString.range(of: $0)!
    let nsRange = NSRange(swiftRange, in: string)
    startIndex = swiftRange.upperBound
    return nsRange
}

И нет причин явно связывать String с NSString.

Но, как вы хотите, nsranges в любом случае Регулярное выражение, как в Ответ Мартина намного эффективнее.

...