I have text:
Lorem ipsum %NAME0% dolor sit amet %NAME1%, consectetur %NAME2% adipiscing elit.
and array names
:
[Bob, Alice, Tom]
I need to get X
index from %NAMEX%
and replace all %NAME0%
, %NAME1%
, %NAME2%
with corresponding item from array: names.get(X)
.
I have
private fun String.replaceWithNames(names: List<String>): String {
var result = this
names.forEachIndexed { index, s ->
result = result.replace("%NAME$index%", s)
}
return result
}
but I am sure that it can be done more optimally.
You could use a regex to go through the string only once and replace each value using the last Regex.replace overload (with lambda). Also, I added some validation in case there is a name reference with an out of bounds index (your current code would just leave the reference there).
private val nameRefRegex = Regex("""%NAME(\d)%""")
private fun String.replaceWithNames(names: List<String>): String {
return nameRefRegex.replace(this) { match ->
val index = match.groupValues[1].toInt()
require(index in names.indices) { "Invalid name index $index, only ${names.size} names available" }
names[index]
}
}
Note: if you need more than 10 names, you could change (\d)
to (\d+)
in the regex (to support more than 1 digit)