代码之家  ›  专栏  ›  技术社区  ›  sfussenegger

Groovy:动态字符串中的变量替换

  •  14
  • sfussenegger  · 技术社区  · 15 年前

    我目前在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!"
    

    有人知道如何让它工作吗?

    干杯

    4 回复  |  直到 15 年前
        1
  •  17
  •   BugOrFeature    8 年前
        2
  •  7
  •   sepp2k    15 年前
    dynamic.replaceAll(/\$\{(\w+)\}/) { m, k -> map[k] }
    
        3
  •  3
  •   Rhubarb    8 年前

    对于一个类似但更一般的问题,我尝试使用SimpleTemplateEngine,但发现它令人沮丧,因为每当在地图中找不到占位符时,就无法避免出现MissingPropertyException。

    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}

        4
  •  3
  •   Ari Manninen    5 年前

    这可以做到:

    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]