Нарезка струн Swift - PullRequest
       19

Нарезка струн Swift

1 голос
/ 02 мая 2020

Я хочу разрезать очень длинную строку от одного слова к другому. Я хочу получить подстроку между этими словами. Для этого я использую следующее расширение строки:

 extension String {
 func slice(from: String, to: String) -> String? {

 guard let rangeFrom = range(of: from)?.upperBound else { return nil }

 guard let rangeTo = self[rangeFrom...].range(of: to)?.lowerBound else { return nil }

 return String(self[rangeFrom..<rangeTo])
 }

Это действительно хорошо работает, но моя raw-строка содержит несколько слов "from" "до", и мне нужна каждая подстрока, которая находится между из этих двух слов, но с моим расширением я могу получить только первую подстроку.

Пример:

let raw = "id:244476end36475677id:383848448end334566777788id:55678900end543"

Я хочу получить следующие подстроки из этого примера необработанной строки:

sub1 = "244476"
sub2 = "383848448"
sub3 = "55678900"

Если я позвоню:

var text = raw.slice(from: "id:" , to: "end")

Я получу только первый случай (text = "244476")

Спасибо, что прочитали. Каждый ответ был бы хорош.

PS: я всегда получаю ошибку, делая фрагменты кода в stackoverflow.

Ответы [ 2 ]

1 голос
/ 02 мая 2020

Вы можете получить диапазоны ваших подстрок, используя while l oop, чтобы повторить поиск с этой точки до конца вашей строки и использовать map для получения подстрок из результирующих диапазонов:

extension StringProtocol {
    func ranges<S:StringProtocol,T:StringProtocol>(between start: S, and end: T, options: String.CompareOptions = []) -> [Range<Index>] {
        var ranges: [Range<Index>] = []
        var startIndex = self.startIndex
        while startIndex < endIndex,
            let lower = self[startIndex...].range(of: start, options: options)?.upperBound,
            let range = self[lower...].range(of: end, options: options) {
            let upper = range.lowerBound
            ranges.append(lower..<upper)
            startIndex = range.upperBound
        }
        return ranges
    }
    func substrings<S:StringProtocol,T:StringProtocol>(between start: S, and end: T, options: String.CompareOptions = []) -> [SubSequence] {
        ranges(between: start, and: end, options: options).map{self[$0]}
    }
}

Тестирование игровой площадки:

let string = """
your text
id:244476end
id:383848448end
id:55678900end
the end
"""

let substrings = string.substrings(between: "id:", and: "end")  // ["244476", "383848448", "55678900"]
1 голос
/ 02 мая 2020

Вместо того, чтобы пытаться анализировать строку от начала до конца, я бы использовал комбинацию существующих методов, чтобы преобразовать ее в желаемый результат. Вот как бы я это сделал:

import Foundation

let raw = "id:244476end36475677id:383848448end334566777788id:55678900end543"

let result = raw
    .components(separatedBy: "id:")
    .filter{ !$0.isEmpty }
    .map { segment -> String in
        let slices = segment.components(separatedBy: "end")
        return slices.first! // Removes the `end` and everything thereafter
    }

print(result) // => ["244476", "383848448", "55678900"]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...