2009-09-24 44 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!" 

誰もがこの作業を取得する方法を知っていますか?

乾杯

答えて

10

あなたは通常、Groovy Templatesでこれを行うだろう。

+0

ありがとう、それは間違いなく私が探していたものでした! – sfussenegger

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

ありがとうございます! applyVoodoo(文字列str、地図マップ){ \tバインディングB =新しいバインディング()DEF ;: はしかし、私は、静的な文字列を使用してに近い何かを探していたとして、私は別の解決策を考え出しました \t for(マップ内)b.setVariable(e.key、e.value); \t GroovyShell sh =新しいGroovyShell(b); \t返されるsh.evaluate( "\" $ {str} \ ""); } – sfussenegger

+0

re:バインディング。これは良いアプローチであり、非常に強力なツールです。地図をBindingコンストラクタに渡すことができます(少なくとも1.6.4用)。 –

+0

信じられないほど強力でエレガントな – raffian

1

類似しているがもっと一般的な問題として、SimpleTemplateEngineを使用しようとしましたが、マップにプレースホルダが見つからないとMissingPropertyExceptionが発生するのを避けることができません。 私はsepp2kの答えのこの一般バリエーションを使用して終了:

"Hello World $s{3}" 

replaceAll(/group/ { k ->が配列でkを埋めるため、これは動作します:最初の要素であるIが望ん与え

def s = '${s1} ${s2} $s{3}' // single quotes! 
result = s.replaceAll(/\$\{(\w+)\}/) { k -> m[k[1]] ?: k[0] } 
println result 

完全一致、第2はグループです。だから、k[0]その後、${(+w)}(サンセリフ文字をエスケープ)のパターンがどこにあるか私の場合は、全体の試合です:"${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]