根据地图可以容纳的值,您可能会遇到一些问题。例如,如果值可能包含其他键标识符,例如
{
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 中的值。如果 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)。