我希望我的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
,您确实会遇到问题。您可以尝试使用 StringBuffer
中的辅助方法构建 Matcher
。对于大输入来说,这应该要快得多:
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) 时间。
仅供参考,对于更复杂的情况,您可以查看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);
使用静态
String.format(String format, Object... args)
方法使用特定参数格式化字符串。
要了解有关如何正确创建有效模板字符串的更多详细信息,请参阅此文档: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html#detail
Java 可能会有字符串模板(可能来自版本 21,作为预览功能)。
请参阅此处字符串模板提案 (JEP 430)。
这将是类似这样的事情:
String name = "John";
String info = STR."I am \{name}";
System.out.println(info); // I am John
Kotlin 与 Java 100% 互操作。它支持开箱即用的更清晰的字符串模板:
val name = "John"
val info = "I am $name"
println(info) // I am John
结合扩展函数,您可以实现与 Java 模板处理器(例如 STR
)相同的功能。