繁体   English   中英

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

[英]How to Generate a String from a String Template in Java?

我希望我的 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*正则表达式并将其替换为值堆栈中的第一个元素。 它循环直到程序在主字符串中找不到任何#value,问题是对于大文本,程序执行时间太长,考虑到所采用的方法,这是正常的。

我还听说过一些使用 Velocity 和 FreeMarker 的模板技术,但我从未使用过它们(非常欢迎对这一点进行任何澄清)。

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

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

如果您在每次替换时创建一个新的完整String ,您确实会遇到问题。 您可以尝试使用Matcher的辅助方法来构建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()方法的参数。

使用静态String.format(String format, Object... args)方法使用特定参数格式化字符串。

要查找有关如何创建有效模板字符串的更多详细信息,请参阅此文档: http//docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html#detail

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

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

仅供参考,对于更复杂的情况,您可以检查Apache Jexl库 是非常轻,具有清晰简单的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);

Java 可能会有字符串模板(可能从版本21开始)。

在此处查看字符串模板提案 (JEP 430)

这将是这样的:

String name = "John";
String info = STR."I am \{name}";
System.out.println(info); // I am John

PS Kotlin与 Java 100% 互操作。 它支持开箱即用的更清晰的字符串模板:

val name = "John"
val info = "I am $name"
println(info) // I am John

结合扩展功能,您可以实现 Java 模板处理器(例如STR )将做的事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM