如何在Java中从字符串模板生成字符串?

如何在Java中从字符串模板生成字符串?,java,regex,string,substring,template-engine,Java,Regex,String,Substring,Template Engine,我希望我的Java应用程序从用户处读取字符串,该字符串可能包含一些标记,例如: String text = " value 1 = #value1 and value 2 = #value2 "; int[] intArray = new int[] {4,5}; 用户还将向应用程序输入一个值数组。作为一名程序员,我不知道字符串中值的确切数目。我想通过编程生成这个字符串: String result = " value 1 = 4 and value 2 = 5 " 为此,我实现了一个方法,

我希望我的Java应用程序从用户处读取字符串,该字符串可能包含一些标记,例如:

String text = " value 1 = #value1 and value 2 = #value2 ";
int[] intArray = new int[] {4,5};
用户还将向应用程序输入一个值数组。作为一名程序员,我不知道字符串中值的确切数目。我想通过编程生成这个字符串:

String result = " value 1 = 4 and value 2 = 5 "
为此,我实现了一个方法,搜索
#value*
正则表达式,并用值堆栈中的第一个元素替换它。它一直循环,直到程序在主字符串中找不到任何#值,问题是对于大文本,程序执行时间太长,考虑到所采用的方法,这是正常的

我也听说过一些使用Velocity和FreeMarker的模板技术,但我从未使用过它们(这一点上的任何澄清都是非常受欢迎的)

所以我的问题是:解决这个问题的最佳方法是什么(最短的执行时间)?


PS:我不需要代码,我只需要一种可以解决这个问题的方法或API

使用static
String.format(String-format,Object…args)
方法使用特定参数格式化字符串

要了解有关如何属性创建有效模板字符串的更多详细信息,请参阅以下文档:

如果每次更换时都要创建一个新的完整的
字符串
,则确实会遇到问题。您可以尝试在运行时使用
Matcher
中的helper方法构建
StringBuffer
。对于大输入,这应该快得多:

String text = " value 1 = #value1 and value 2 = #value2 ";
int[] intArray = new int[] { 4, 5 };
Pattern p = Pattern.compile("#value(\\d+)");
Matcher m = p.matcher(text);
StringBuffer result = new StringBuffer();
while (m.find()) {
    m.appendReplacement(result, String.valueOf(intArray[Integer.parseInt(m.group(1)) - 1]));
}
m.appendTail(result);
System.out.println(result.toString());
编辑

许多人指出,
StringBuilder
更适合这份工作。我同意,但不幸的是,
Matcher
API不接受
StringBuilder
作为
appendReplacement()
appendTail()
方法的参数。

有大量的模板/表达式语言引擎可以帮助您实现这一点,
Velocity
Freemaker
也可以解决这个问题,但是对于这个相当简单的任务来说,它们可能太重了

正如@Keppil(+1)已经提到的,最简单的方法是使用regexp。正确的代码将花费O(n)时间

仅供参考,对于更复杂的情况,您可以查看。它非常轻巧,具有清晰简单的API。您的案例可以通过以下代码解决:

    JexlEngine jexl = new JexlEngine();
    Expression expression = jexl.createExpression("value 1 = #value1 value 2 = #value2");
    int[] values = {1, 2};
    JexlContext context = new MapContext();
    for (int i = 0; i <  values.length; i++) {
        context.set("#value" + (i + 1), values[i]);
    }
    String result = (String)expression.evaluate(context);
JexlEngine jexl=新的JexlEngine();
Expression=jexl.createExpression(“值1=#值1值2=#值2”);
int[]值={1,2};
JexlContext=new MapContext();
对于(int i=0;i
最短执行时间?你这是什么意思?另外,您看过String.format()吗?pft。。。某些字符串操作的最短执行时间-要转换多少个字符串?10? 10'000? 10mio?如上所述^ ^如果他担心最快的执行时间,那么
StringBuilder
会更快,但缺乏线程安全性。@Rudi:添加了一条注释来说明这一点。你不是第一个指出这一点的人。:)每天学习新的东西。感谢您的澄清。freemarker vs velocity vs Stringtemplate哪个更好?很难说,它们都是好的LIB,这实际上取决于使用模式以及您对API/功能集的满意程度。如果您需要html/xml处理,那么我建议您也看看Thymeleaf。适用于HTML/XML(网页/丰富的电子邮件)模板处理。