您所描述的通常称为模板化。那里有许多模板应用程序和库,但如果您只想要一个快速而简单的解决方案,可以使用正则表达式轻松实现。
在许多正则表达式风格中,您将使用内置回调或标注机制,如 PHP 的preg_replace_callback
函数或 Perl 的/e
和/ee
修饰符。Java 没有类似的东西,但它提供了 API 让您自己实现它。这是一个例子:
import java.util.*;
import java.util.regex.*;
public class Test
{
public static void main(String[] args) throws Exception
{
String s = "Lorem ipsum {foo} impedit civibus ei pri, legimus\n" +
"antiopam no {marco}, quo id everti forensibus maiestatis.";
Map<String,Object> p = new HashMap<String,Object>()
{{
put("foo", "BAR");
put("marco", "POLO!");
}};
System.out.printf("%s%n%n%s%n", s, supplant(s, p));
}
public static CharSequence supplant(CharSequence message, Map<String,Object> params)
{
Matcher m = Pattern.compile("\\{(\\w+)\\}").matcher(message);
StringBuffer sb = new StringBuffer();
while (m.find())
{
m.appendReplacement(sb, "");
String key = m.group(1);
sb.append(params.get(key).toString());
}
m.appendTail(sb);
return sb.toString();
}
}
显然,这段代码遗漏了一些基本组件(主要是异常处理),但它展示了这种技术的要点:
- 使用括号捕获大括号内的内容,然后通过调用
group(1)
Matcher 来访问它。
- 用于
appendReplacement(sb, "")
附加上一个匹配项(如果有)和当前匹配项之间出现的任何文本。
- 查找替换并使用 StringBuffer 的
append()
方法附加它。(您可以通过将替换字符串作为第二个参数传递给 来组合步骤 2 和 3 appendReplacement()
,但是您必须注意字符串中的美元符号和反斜杠,它们会受到特殊处理。这种方式要简单得多。)
- 用于
appendTail(sb)
附加最后一场比赛后剩下的任何内容。
有几个人发布了帮助类,让您无需编写所有样板代码即可完成此类任务。我最喜欢的是 Elliott Hughes 的Rewriter。