Reputation: 11251
I would like to substitute %s
with the value
<server>
<id>artifactory</id>
<username>%s</username>
<password>%s</password>
</server>
Is there any myString.format("name", "pass")
method in groovy?
Upvotes: 23
Views: 73000
Reputation: 7705
Groovy has a SimpleTemplateEngine that you can use. This may be an overkill for simple cases, but for example let's say that you want to read a template from a file, and inject variables there. Using %s
would be a nightmare. SimpleTemplateEngine is a way to go here:
import groovy.text.SimpleTemplateEngine
def engine = new SimpleTemplateEngine()
def template = 'User: ${user}\nPassword: ${password}'
def binding = [
"user": "root",
"password": "toor"
]
def result = engine.createTemplate(template).make(binding).toString()
assert result == "User: root\nPassword: toor"
So to summarize:
Groovy String Interpolation
def user = "root"
def password = "toor"
// Note: Remember to use single quotes!
def result = "User: ${user}\nPassword: ${password}"
assert result == "User: root\nPassword: toor"
Pros:
Cons:
"Hello ${someRandomFunction('Arnold', anotherFunction(arr[1]))}"
Java String.format
// Now template can be defined before variables
def template = "User: %s\nPassword: %s"
def user = "root"
def password = "toor"
def result = String.format(template, user, password)
assert result == "User: root\nPassword: toor"
Pros:
Cons:
Hello %s, I'm %s and I'm %d old. I live in %s, %s. My %s is %s.
Groovy sprintf
def template = "User: %s\nPassword: %s"
def result = sprintf(template, ["root", "toor"])
assert result == "User: root\nPassword: toor"
Pros:
Java String.format
Cons:
Java String.format
expect cons with passing variablesGroovy SimpleTemplateEngine
import groovy.text.SimpleTemplateEngine
def engine = new SimpleTemplateEngine()
def template = 'User: ${user}\nPassword: ${password}'
def binding = [
"user": "root",
"password": "toor"
]
def result = engine.createTemplate(template).make(binding).toString()
assert result == "User: root\nPassword: toor"
Pros:
Cons:
"Hello ${someRandomFunction('Arnold', anotherFunction(arr[1]))}"
Generally, my favorite is Groovy's String interpolation and the SimpleTemplateEngine, because I don't mind importing one class more. But choice is yours :)
Upvotes: 0
Reputation: 2584
Collecting the answers and comments above in the single place, there are two approaches:
String.format
functionality see above, which is in groovy wrapped into convenience function sprintf
see e.g. here or hereIn my personal opinion, first option is better fit for the originally asked question, because it allows for creating "template" strings, which can be then used with arbitrary parameters in arbitrary place in the code arbitrary number of times. This seems to be the use-case in the original question.
Generally there are two major differences between string interpolation and sprintf:
{-> expr}
), it still does not have explicit act of template application, but rather rely on externally defined variables with particular names, which is in my opinion less reliable.As an illustration for the templating usecase, consider:
// can be defined in the same function, or as static variable in the class or even
// in other class
final String URL_TEMPLATE = 'http://fake.weather.com/rest/%s' // arg - country abbreviation
// ...
// Here we want to get weather for different countries.
def countries = ['US', 'DE', 'GB']
for (country in countries) {
def url = URL_TEMPLATE.format(country)
// send the request, accumulate the results
}
This solution is not easy to use using string interpolation. Of course, I admit, that it is still possible to build the solution also based on string interpolation, but it would look much different.
Upvotes: 3
Reputation: 3932
You can use sprintf from DefaultGroovyMethods
def name = "name"
def pass = "pass"
String formatted = """
<server>
<id>artifactory</id>
<username>$name</username>
<password>$pass</password>
</server>
"""
def f = sprintf( formatted, name, pass )
Upvotes: 5
Reputation: 45339
Groovy has built-in support for string interpolation. All you need is to use a GString
:
def name = "name"
def pass = "pass"
String formatted = """
<server>
<id>artifactory</id>
<username>$name</username>
<password>$pass</password>
</server>
"""
If your values come as an array or collection, you can even use params[n]
instead of named variables ($name
), like this:
def params = ['name', 'pass']
String formatted = """
<server>
<id>artifactory</id>
<username>${params[0]}</username>
<password>${params[1]}</password>
</server>
"""
If your string needs to be externalized, you can use template engines
Beside this, you can use the normal Java String.format
:
def formatted = String.format(myString, "name", "pass")
Upvotes: 27
Reputation: 28634
groovy based on java and in java there is a format
method in String
class
so this should work
def s='''<server>
<id>artifactory</id>
<username>%s</username>
<password>%s</password>
</server>'''
println String.format(s, "name", "pass")
Upvotes: 18