比如有个字符串模板:
今天是${date}, 我准备了${money}元,打算去${place}旅游.
当我传递一个map,指定上述参数的值后, 需要对字符串模板进行渲染
此类需求常见于短信模板
一、使用freemarker进行处理
- FreeMarker是一款模板引擎
- 模板和数据是FreeMarker来生成输出所必须的组成部分:模板 + 数据模型 = 输出
- 我们常用语freemarker进行诸如html渲染,代码生成等功能
使用freemarker进行字符串渲染自然也是可以的,如下:
public static String renderString(String templateString, Map<String, ?> model) throws Exception {
StringWriter result = new StringWriter();
Template t = new Template("name", templateString, new Configuration(Configuration.VERSION_2_3_23));
t.process(model, result);
return result.toString();
}
二、使用正则进行处理
- 正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
- java对正则的支持很强大,对字符串的处理能力也极强
使用正则进行字符串渲染如下:
private final static Pattern NAMED_FORMAT_PATTERN = Pattern.compile("[$]\\{(?<key>.*?)}");
public static String namedFormat(String format, Map<String, ?> data) {
StringBuffer buf = new StringBuffer();
Matcher matcher = NAMED_FORMAT_PATTERN.matcher(format);
while (matcher.find()) {
String namedParam = matcher.group("key");
Object value = data.get(namedParam);
matcher.appendReplacement(buf, value == null ? "null" : value.toString());
}
matcher.appendTail(buf);
return buf.toString();
}
以上正则中使用到了jdk7中的一个正则新特性,命名捕获。
可以参考:java正则命名捕获
三、对比
- 对于字符串渲染来说,使用正则的方式效率要远高于使用freemark
- freemark渲染更适合于那种场景更加复杂的渲染,比如需要各种if标签,for标签等
- 对于简单的渲染来说,使用正则的方式会更加好