Замените соответствующие значения регулярных выражений в строке на правильное значение из словаря - PullRequest
0 голосов
/ 02 ноября 2018

У меня есть строка

var text = "the {animal} jumped over the {description} fox"

и словарь

var dictionary = ["animal":"dog" , "description", "jumped"]

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

 //alpha numeric characters, - and _
 let regex = try NSRegularExpression(pattern: "{[a-zA-Z0-9-_]}", options: .caseInsensitive)

var text = "the {animal} jumped over the {description} fox"
let all = NSRange(location: 0, length: text.count)

regex.enumerateMatches(in: text, options: [], range: all) { (checkingResult, matchingFlags, _) in
    guard let resultRange = checkingResult?.range else {
        print("error getting result range")
        return
    }
    //at this point, i was hoping that (resultRange.lowerbound, resultRange,upperBound) would be the start and end index of my regex match. 
    //so print(text[resultRange.lowerBound..<resultRange.upperBound] should give me {animal}
    //so i could get the word between the curly braces, and replace it in the sentence with it dictionary value         
}

, но быстрое манипулирование струнами меня невероятно смущает, и это, похоже, не работает.

Это правильное направление?

Спасибо

1 Ответ

0 голосов
/ 02 ноября 2018

Вот одно из решений, которое работает. Обработка строк еще сложнее, потому что вам также приходится иметь дело с NSRange.

extension String {
    func format(with parameters: [String: Any]) -> String {
        var result = self

        //Handles keys with letters, numbers, underscore, and hyphen
        let regex = try! NSRegularExpression(pattern: "\\{([-A-Za-z0-9_]*)\\}", options: [])

        // Get all of the matching keys in the curly braces
        let matches = regex.matches(in: self, options: [], range: NSRange(self.startIndex..<self.endIndex, in: self))

        // Iterate in reverse to avoid messing up the ranges as the keys are replaced with the values
        for match in matches.reversed() {
            // Make sure there are two matches each
            // range 0 includes the curly braces
            // range 1 includes just the key name in the curly braces
            if match.numberOfRanges == 2 {
                // Make sure the ranges are valid (this should never fail)
                if let keyRange = Range(match.range(at: 1), in: self), let fullRange = Range(match.range(at: 0), in: self) {
                    // Get the key in the curly braces
                    let key = String(self[keyRange])
                    // Get that value from the dictionary
                    if let val = parameters[key] {
                        result.replaceSubrange(fullRange, with: "\(val)")
                    }
                }
            }
        }

        return result
    }
}

var text = "the {animal} jumped over the {description} fox"
var dictionary = ["animal":"dog" , "description": "jumped"]
print(text.format(with: dictionary))

Выход:

собака перепрыгнула через прыгнувшую лису

Этот код оставляет исходный {keyname} в строке, если он не найден в словаре. Настройте этот код по своему усмотрению.

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