2009-09-24 71 views
12

我目前在groovy中面临变量替换相关的问题。虽然这是很简单的: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!" 

有谁知道如何得到这个工作?

干杯

回答

5
dynamic.replaceAll(/\$\{(\w+)\}/) { m, k -> map[k] } 
+0

This Works,thanks! 然而,正如我一直在寻找的东西,更接近于使用静态字符串,我想出了另一种解决方案: 高清applyVoodoo(字符串str,地图地图){ \t绑定B =新的Binding(); (e在地图)b.setVariable(e.key,e.value); GroovyShell sh = new GroovyShell(b); GroovyShell(b); GroovyShell(b); GroovyShell \t return sh.evaluate(“\”$ {str} \“”); } – sfussenegger 2009-09-24 16:24:15

+0

re:绑定。这是一个很好的方法和一个非常强大的工具。请注意,您可以将地图传递给Binding构造函数(至少1.6.4)。 – 2009-09-24 21:05:50

+0

令人难以置信的强大和优雅 – raffian 2015-09-05 22:51:16

1

对于类似但更普遍的问题,我尝试使用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我在使用猫王?:分全k0这是未膨胀的变量,像${s3}

2

如果我们能够接受变量引用轻微的修改,我会做这样的:

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]