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

mgdq6dx1  于 2022-12-24  发布在  Java
关注(0)|答案(4)|浏览(161)

我希望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,可以解决这个问题。*
quhf5bfb

quhf5bfb1#

如果你在每次替换的时候都创建一个新的完整的String,你会遇到一些问题。你可以尝试使用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更适合这项工作,我同意,但不幸的是MatcherAPI不接受StringBuilder作为appendReplacement()appendTail()方法的参数。

oiopk7p5

oiopk7p52#

有大量的模板/表达式语言引擎可以帮助您解决这个问题,VelocityFreemaker也可以解决这个问题,但是对于这个相当简单的任务来说,它们可能太重了。
正如@Keppil(+1)提到的,最简单的方法是使用regexp,正确的代码需要O(n)时间。
仅供参考,对于更复杂的情况,你可以检查Apache Jexl library。是相当轻,有明确和简单的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);
jtoj6r0c

jtoj6r0c3#

使用静态的String.format(String format, Object... args)方法来格式化带有特定参数的字符串。
要了解有关如何正确创建有效模板字符串的详细信息,请参阅此文档:http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html#detail

tnkciper

tnkciper4#

Java可能会有字符串模板(可能来自版本21)。
参见the string templates proposal (JEP 430) here
它将是这样的:

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

P.S. Kotlin可以100%与Java互操作,它支持更干净的字符串模板:

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

extension functions结合使用,可以实现与Java模板处理器(例如STR)相同的功能。

相关问题