谢谢大家的回答!
Gizmo 的答案绝对是开箱即用的,并且是一个很好的解决方案,但不幸的是,格式不适合 Formatter 类在这种情况下所做的事情。
亚当佩恩特用正确的模式真正抓住了问题的核心。
Peter Nix 和 Sean Bright 有一个很好的解决方法来避免正则表达式的所有复杂性,但是如果有错误的标记,我需要提出一些错误,但没有这样做。
但就做一个正则表达式和一个合理的替换循环而言,这是我想出的答案(在谷歌和现有答案的帮助下,包括 Sean Bright 关于如何使用 group(1) vs group() ):
private static Pattern tokenPattern = Pattern.compile("\\{([^}]*)\\}");
public static String process(String template, Map<String, Object> params) {
StringBuffer sb = new StringBuffer();
Matcher myMatcher = tokenPattern.matcher(template);
while (myMatcher.find()) {
String field = myMatcher.group(1);
myMatcher.appendReplacement(sb, "");
sb.append(doParameter(field, params));
}
myMatcher.appendTail(sb);
return sb.toString();
}
doParameter 从地图中获取值并将其转换为字符串,如果不存在则抛出异常。
另请注意,我更改了模式以查找空括号(即 {}),因为这是明确检查的错误条件。
编辑:请注意, appendReplacement 与字符串的内容无关。根据 javadocs,它将 $ 和反斜杠识别为特殊字符,因此我在上面的示例中添加了一些转义来处理它。没有以最注重性能的方式完成,但在我的情况下,这还不够大,不值得尝试对字符串创建进行微优化。
感谢 Alan M 的评论,这可以更简单地避免 appendReplacement 的特殊字符问题。