Replacing multiple text tokens in Swift
Let’s see how to replace multiple tokens in string. As an example problem to solve we will use this string:
The quick <color_1> <animal_1> jumps over the lazy <animal_2>
String extension for replacing tokens
Token’s format is
< text _ numbers > what can be turned into regular expression:
We’ll extend string and add a function what takes in regular expression and closure responsible of providing replacement strings. For finding tokens, we’ll use NSRegularExpression and get all the matches in the string. Next step is to reverse enumerate matches and replace tokens. Reverse enumerating is required it ensures that token ranges are constant. If we would start replacing from the first match, then all the succeeding ranges should be shifted based on the length difference of all the preceding tokens and replacements. In this case reduce is convenient because we can enumerate all the matches and then mutating the copy of the initial string with very few lines. Another aspect to note is that NSRegularExpression uses NSRange instead of <a rel="noreferrer noopener" aria-label="RangeRange<String.Index>. Therefore we need to convert ranges from one type to another making sure character indexes match.
This function can now be used with custom logic when providing replacements. For example: we can have a simple mapping or even returning the same replacement string.
When we would like to do multiple replacements in a string, then one of the approaches is to get all the replacement ranges and then reverse enumerating the ranges and making replacements. In this way we can avoid having complex code trying to adjust based on the length difference of the source and replacement string.