https://kotlinlang.org logo
#getting-started
Title
# getting-started
a

Andrey Tabakov

01/25/2023, 9:21 AM
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

Sam

01/25/2023, 9:32 AM
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

Andrey Tabakov

01/25/2023, 9:34 AM
not really, I want a dynamic substitution based on variables in string (runtime)
s

Stylianos Gakis

01/25/2023, 9:44 AM
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

Andrey Tabakov

01/25/2023, 9:46 AM
it's an another case
s

Stylianos Gakis

01/25/2023, 9:49 AM
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

CLOVIS

01/25/2023, 10:04 AM
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

ephemient

01/25/2023, 10:11 AM
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
12 Views