我目前正面临着groovy中与变量替换相关的问题。虽然这非常简单:
Map map = [s1:"Hello", s2:"World"]
println "${map.s1} ${map.s2}!" // "Hello World!"
由于这有效,我很确定这样的事情也应该有效:
Map map = [s1:"Hello", s2:"World"]
def dynamic = loadStringFromFile();
println "${dynamic} ${dynamic.class}" // "${s1} ${s2}! (java.lang.String)"
// now the voodoo part
println applyVoodoo(dynamic, map) // "Hello World!"
有人知道如何让这个工作吗?
干杯
答案 0 :(得分:12)
您通常会使用Groovy Templates执行此操作。
答案 1 :(得分:7)
dynamic.replaceAll(/\$\{(\w+)\}/) { m, k -> map[k] }
答案 2 :(得分:3)
如果我们可以接受对变量引用的轻微修改,我会这样做:
Map map = [s1:"Hello", s2:"World"]
def dynamic = '${x.s1} ${x.s2}!' // Plain string
println "${dynamic} ${dynamic.class}" // "${x.s1} ${x.s2}! class java.lang.String"
// The voodoo part
println Eval.x(map, '"' + dynamic +'"') // Hello World!
表达式"${x.s1} ${x.s2}!"
使用变量插值求值为GString
。这意味着,我们可以更灵活地使用变量引用,而不会出现Groovy模板的复杂性。
dynamic = 'keys: ${x.values()}'
println Eval.x(map, '"' + dynamic +'"') // keys: [Hello, World]
答案 3 :(得分:2)
对于类似但更普遍的问题,我尝试使用SimpleTemplateEngine,但发现令人沮丧的是,只要在地图中找不到占位符,就无法避免出现MissingPropertyException。 我最终使用了sepp2k答案的这种广义变体:
def s = '${s1} ${s2} $s{3}' // single quotes!
result = s.replaceAll(/\$\{(\w+)\}/) { k -> m[k[1]] ?: k[0] }
println result
给出我想要的东西:
"Hello World $s{3}"
这是有效的,因为replaceAll(/group/ { k ->
用数组填充k
:第一个元素是完全匹配,第二个元素是组。所以在我的情况下,模式是(没有转义字符)${(+w)}
然后k[0]
是整个匹配:"${s1}"
和k[1]
组匹配"s1"
,所以
map[k[1]] = map["s1"] = "Hello"
如果map[k1]
是null
我使用elvis ?:
来填充完整的k0
,这是未展开的变量,例如${s3}