Hi, is there any convenient way to make a string s...
# getting-started
a
Hi, is there any convenient way to make a string substitution, like format but with variables? example:
Copy code
makeString("any string with {variableOne} {variableTwo}", mapOf("variableOne" to "1", "variableTwo" to "2")) 

// any string with 1 2
s
Are you looking for something more than just string interpolation? e.g.
Copy code
val x = 1
val s = "The value of x is $x"
a
not really, I want a dynamic substitution based on variables in string (runtime)
s
https://comahe-de.github.io/i18n4k/ this library does allow you to do something like this for localization. You may want to look into the internals of it, it may have what you want. It does stuff like for a string
Helloo, {0}!
if you call it with
println(MyMessages.sayHello("i18n4k"))
it will print “Hello, i18n4k!“.
a
it's an another case
s
Yes, however they are doing what you are asking, so I just suggested you look at the source code and see how they do it, it might help you out.
c
If you decide to do that yourself, be very careful with what logic you encode. This is the mother of all injection bugs (from memory corruption in C, path traversal using JS'
replace
, and of course the entire Log4Shell debacle)
You're essentially making values (your string) able to do things, and at some point an attacker will use that against you.
e
simple Python-esque string formatting:
Copy code
private val namedArgumentPattern = """%\((\w+)\)""".toRegex()
operator fun CharSequence.rem(namedArguments: Map<String, Any?>): String =
    namedArgumentPattern.replace(this) { match ->
        val (name) = match.destructured
        namedArguments.getValue(name).toString()
    }

println("%(foo), %(bar)!" % mapOf("foo" to "Hello", "bar" to "world"))
🙌 1
doesn't handle escaping or formatting like the original though. if you want to do that, you'll probably want to write a proper format string parser