2009-09-24 30 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]