是否有预先编写的方法来替换带有预定义常量的字符串中的美元符号名称变量?
例如,以下代码:
Map<String, Object> myVars = new TreeMap<String, Object>();
String str = "The current year is ${currentYear}.";
myVars.put("currentYear", "2014");
System.out.println(Replacer.replaceVars(str, myVars));
...会有这个输出:
The current year is 2014.
答案 0 :(得分:1)
查看MessageFormat
课程。你的例子看起来像这样:
int currentYear = 2014;
String str = "The current year is {0}.";
str = MessageFormat.format(str, currentYear);
这可能是最好的版本,但您也可以使用正则表达式:
public String format (String input, Map<String, String> replacement)
{
for (String key : replacement.keySet())
input = input.replaceAll("\\${"+replacement+"}", replacement.get(key));
return input;
}
答案 1 :(得分:1)
如果您需要支持更高级的用例,Spring也会这样做。我能够将以下类中的代码用于我的用例。请参阅parseStringValue
方法。
在您的情况下,您需要传递使用PlaceholderResolver
的{{1}}来解析占位符。
答案 2 :(得分:0)
我不知道任何支持此行为的标准Java类,但编写工具不会那么难。以下是此类解决方案的示例:
class Replacer {
private static Pattern pattern = Pattern.compile("\\$\\{(?<key>[^}]*)\\}");
public static String replaceVars(String format, Map<String, ?> map) {
StringBuffer sb = new StringBuffer();
Matcher m = pattern.matcher(format);
while (m.find()) {
String key = m.group("key");
if (map.containsKey(key)) {//replace if founded key exists in map
m.appendReplacement(sb, map.get(key).toString());
} else {//do not replace, or to be precise replace with same value
m.appendReplacement(sb, m.group());
}
}
m.appendTail(sb);
return sb.toString();
}
}
我们可以利用Java 8中引入的默认方法getOrDefault
来映射接口并替换
while (m.find()) {
String key = m.group("key");
if (map.containsKey(key)) {//replace if founded key exists in map
m.appendReplacement(sb, map.get(key).toString());
} else {//do not replace, or to be precise replace with same value
m.appendReplacement(sb, m.group());
}
}
m.appendTail(sb);
带
while (m.find())
m.appendReplacement(sb, map.getOrDefault(m.group("key"), m.group()));
m.appendTail(sb);
但是为了能够使用这种方法,我们首先需要在地图中指定值的类型 - 换句话说,我们需要将接受的地图类型从Map<String, ?> map
更改为类似Map<String, String> map
的类型。