Search code examples
regexkotlinregex-group

Replace all regex occurrences with item from array by index from regex group


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.


Solution

  • 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)