私は現在、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!"
誰かがこれを機能させる方法を知っていますか?
乾杯
通常、これは Groovy Templates で行います。
dynamic.replaceAll(/\$\{(\w+)\}/) { m, k -> map[k] }
これはそれをします:
Map map = [s1:"Hello", s2:"World"]
String dynamic = '${s1} ${s2}!' // Plain string, can be loaded from a file
// Voodoo part
GroovyShell Shell = new GroovyShell(new Binding(map))
println Shell.evaluate('"' + dynamic +'"') // Hello World!
dynamic
文字列が二重引用符で囲まれている場合、変数補間を使用してGString
と評価されます。つまり、Groovyテンプレートを複雑にすることなく、変数参照の柔軟性をすべて備えています。
変数参照のわずかな変更を受け入れることができる場合は、さらに簡単なオプションがあります。
Map map = [s1:"Hello", s2:"World"]
String dynamic = '${x.s1} ${x.s2}!' // Plain string
// The voodoo part
println Eval.x(map, '"' + dynamic +'"') // Hello World!
// This way, we can also access the map methods
dynamic = 'values: ${x.values()}'
println Eval.x(map, '"' + dynamic +'"') // values: [Hello, World]
同様の、しかしより一般的な問題については、SimpleTemplateEngineを使用してみましたが、マップにプレースホルダーが見つからない場合は常にMissingPropertyExceptionが発生するのを避けられないという点でイライラしました。私はsepp2kの答えのこの一般化されたバリエーションを使用することになりました:
_def s = '${s1} ${s2} $s{3}' // single quotes!
result = s.replaceAll(/\$\{(\w+)\}/) { k -> m[k[1]] ?: k[0] }
println result
_
これは[〜#〜] i [〜#〜]欲しかったものを与えます:
_"Hello World $s{3}"
_
これは、_replaceAll(/group/ { k ->
_がk
を配列で埋めるために機能します。最初の要素は完全一致で、2番目の要素はグループです。したがって、パターンが(sans escape chars)${(+w)}
の場合、_k[0]
_は完全一致です:_"${s1}"
_および_k[1]
_グループ一致_"s1"
_ 、 そう
_map[k[1]] = map["s1"] = "Hello"
_
_map[k1]
_がnull
の場合、elvis _?:
_を使用して、_k0
_のような非拡張変数である完全な_${s3}
_をサブインします。