Как преобразовать строку?

Всем привет! Мне нужно преобразовать строку "4{b3{a}}" в "baaabaaabaaabaaa". Как мне извлечь цифры из первой строки при использовании regex? Мой regex: NSRegularExpression(pattern: "[\^{a-z}\{1-9}$?]*", options: .caseInsensitive)


Ответы (1 шт):

Автор решения: schmidt9

Вот пример решения данной задачи, за основу я взял регулярку, предложенную ipatev_nn, добавил в нее скобки для группировки, хотя данная регулярка подходит только для строки вида 4{b3{a}} и не подойдет для строк с большей вложенностью групп (например 4{b3{a6{c}}}), проверить регулярку с разбором можно здесь

        let str = NSString("4{b3{a}}")
        let pattern = "^([0-9]+)\\{([a-z]+)([0-9]+)\\{([a-z]+)\\}\\}$"
        let regex = try! NSRegularExpression(pattern: pattern, options: [])
        
        let matches = regex.matches(in: str as String, options: [], range: NSRange(location: 0, length: str.length))
        var values = [String]()
        
        for match in matches {
            for rangeIndex in 1..<match.numberOfRanges {
                let range = match.range(at: rangeIndex)
                let value = str.substring(with: range)
                print(range, value)
                values.append(value)
            }
        }

В результате получаем такой массив, где четные позиции занимает подстрока, которую нужно повторить, а нечетные - количество повторов

4
b
3
a

Генерируем строку на основе массива, начинаем с внутренней группы (с конца массива) и постепенно формируем строку тоже с конца, каждый раз вставляя новые данные в ее начало

        var result = ""
        
        for i in stride(from: values.count - 2, through: 0, by: -2) {
            let repeatCount = Int(values[i])!
            let value = values[i + 1]
            result.insert(contentsOf: value, at: result.startIndex)
            result = String(repeating: result, count: repeatCount)
        }

Полный пример

    func buildString() {
        
        // parse encoded string
        
        let str = NSString("4{b3{a}}")
        let pattern = "^([0-9]+)\\{([a-z]+)([0-9]+)\\{([a-z]+)\\}\\}$"
        let regex = try! NSRegularExpression(pattern: pattern, options: [])
        
        let matches = regex.matches(in: str as String, options: [], range: NSRange(location: 0, length: str.length))
        var values = [String]()
        
        for match in matches {
            for rangeIndex in 1..<match.numberOfRanges {
                let range = match.range(at: rangeIndex)
                let value = str.substring(with: range)
                print(range, value)
                values.append(value)
            }
        }
        
        // build result string
        
        var result = ""
        
        for i in stride(from: values.count - 2, through: 0, by: -2) {
            let repeatCount = Int(values[i])!
            let value = values[i + 1]
            result.insert(contentsOf: value, at: result.startIndex)
            result = String(repeating: result, count: repeatCount)
        }
        
        print(result)
    }
→ Ссылка