在主字符串中插入基于字符串关键字值的映射键

时间:2019-04-27 05:51:34

标签: java

在Java中,我必须根据主字符串中的键插入字符串值。 例如-

主字符串-

sellers(seller: $sellerId, shipment: $shipmentId)

键和值的映射-

{
    sellerId: abc
    shipmentId: 123
}

因此插入后将变为

sellers(seller: abc, shipment: 123)

我知道我可以进行字符串替换。但这似乎并不是一个好方法。所以只是想知道这里是否有标准的方法或更好的方法?

3 个答案:

答案 0 :(得分:1)

您可以考虑以下两种方法:

1-循环映射条目,并执行简单的字符串替换(请注意,这假定字符串中每个var均出现一次;如果不是这种情况,则需要使用replaceAll):

String text = "sellers(seller: $sellerId, shipment: $shipmentId)";
Map<String, Object> binding = ...;

String result = text;
for (Entry<String, Object> entry : binding.entrySet()) {
    result = result.replace("$" + entry.getKey(), String.valueOf(entry.getValue()));
}

2-对于高级用例,您想使用适当的模板引擎。这是一个使用groovy's simple template engine的示例(在Java中通过添加groovy jar使用):

groovy.text.SimpleTemplateEngine engine = new groovy.text.SimpleTemplateEngine();
Writable template = engine.createTemplate(text).make(binding);

String result = template.toString();

请注意,groovy替换了前缀为$的变量名,因此这无需更改即可工作(使之成为当前语法的不错选择)。

两者都能产生预期的结果,但是您必须根据其结果进行选择。

答案 1 :(得分:0)

在这里可以选择字符串格式

Map<String, Integer> yourMap = new HashMap<>();
yourMap.put("abc", 123);

for (Map.Entry<String, Integer> entry : yourMap.entrySet()) {
   String output = String.format("sellers(seller: %s, shipment: %d)", entry.getKey(), entry.getValue());
   System.out.println("output = " + output);
}

答案 2 :(得分:0)

依赖于值映射可以使您面临一些问题。例如,如果value可能包含其他键标识符,例如

{
    foo: $bar
    bar: 123
}

然后使用一系列replace(mapEntryKey, mapEntryValue)可以更改字符串,如

abc $foo efg $bar 

首先进入$foo->$bar

abc $bar efg $bar

然后是$bar->123

abc 123 efg 123

这不是我们想要的。

为避免此类问题,我们应该仅对模板进行一次迭代,搜索每个$key并将其替换为在map中为其存储的值。如果地图不包含此类键,我们可以将其保留(将其自身替换)。

我们可以使用Matcher#replaceAll​(Function<MatchResult,​String> replacer)来做到这一点。顺便说一句,如果地图值可以包含$\,它们也是替换的元字符,我们需要对其进行转义。为此,我们可以使用Mather#quoteReplacement方法。

演示:

Map<String, String> map = Map.of("sellerId", "abc",
        "shipmentId", "123");
String yourTemplate = "sellers(seller: $sellerId, shipment: $shipmentId)";

Pattern p = Pattern.compile("\\$(\\w+)");
Matcher m = p.matcher(yourTemplate);

String replaced = m.replaceAll(match -> {
    if(map.containsKey(match.group(1))){
        return Matcher.quoteReplacement(map.get(match.group(1)));
    }else{
        return Matcher.quoteReplacement(match.group());
    }
});
System.out.println(replaced);

输出:sellers(seller: abc, shipment: 123)