Is there any built-in solution that allows to substitute strings in a manner of NSExpression
does (i.e. with a binding dictionary provided)?
So instead of:
let s = String(format: "%@ %@", arguments: ["foo", "bar"]) // "foo bar"
we have:
let s = String(format: "$foo $bar", ["foo": "hello", "bar": "world"]) // hello world
P.S. I'm aware of replaceOccurrences
, I need NSExpression style substitution. Thanks!
As already mentioned by matt you would need to implement your own method. You can use a regex to match the ranges of all keys of your dictionary that starts with a dollar sign "\\$\\w+"
and use the method "ranges(of:)"
of this answer to replace the subranges of your string creating a custom initializer extending String:
extension String {
init(format: String, _ dictionary: [String: String]) {
var result = format
for range in format.ranges(of: "\\$\\w+", options: .regularExpression).reversed() {
result.replaceSubrange(range, with: dictionary[String(format[range].dropFirst())] ?? "")
}
self = result
}
}
Playground testing:
let result = String(format: "$foo $bar", ["foo": "hello", "bar": "world"])
print(result) // "hello world"