【问题标题】:Java - How to deal with ${param} [duplicate]Java - 如何处理 ${param} [重复]
【发布时间】:2018-12-05 03:51:32
【问题描述】:

客户端传给我一个参数str = "${param0},${param1}"。 我想将${param0} ${param1} 替换为我从数据库中查询的值。

比如

//str = "${param0},${param1}"
//str = "${param0},${param1}, ${param2}"
//...
public String format(String str) {

    String param0 = repository.query0();
    //expect
    str = "param0,${param1}";

    String param1 = repository.query1();
    //expect
    str = "param0,param1,${param2}";

    return str;
}

我知道java.lang.String#replace可以解决问题。但是参数str 是不确定的。它也可以是str = "${param0}, ${param1}, ${param2}" 或更多。有什么方法可以满足我的要求吗?

【问题讨论】:

  • replace + 循环?
  • 你能给我们看一些输入和输出的例子吗!
  • 如何将输入字符串与从数据库查询的值匹配?带索引?
  • @HalayemAnis 同名
  • 所以请清楚地更新您的问题,

标签: java replace placeholder


【解决方案1】:

如果您确信它将始终采用${paramX} 的格式,那么您可以执行以下操作:

String str = ...;
for (int i = 0; i < results.length; i++)
{
    str = str.replace("${param" + i + "}", results[i]);
}

将 for 循环的内容和 resutls[i] 部分替换为您访问查询返回的数据的方式。

如果您不能依赖 ${paramX} 是按顺序排列的,则可以使用以下代码来使用更 hacky 的解决方案:

// create a new StringBuilder to reduce concatentation
StringBuilder result = new StringBuilder();

// our warped string input
String str = "${param0}, ${param12}${param1234}${param2}";

// split it anywhere that is formatted with ${paramXXXX}
String[] parts = str.split("\\$\\{param[0-9]{1,}\\}");

// loop through the pieces
for (int i = 0; i < parts.length; i++)
{
    // get the parts of the string that are not ${paramXXXX}
    result.append(parts[i]);

    // the results from the query.
    result.append(queryResults[i]); // Replace with the proper way to read your query results
}

无论输入如何,只要查询结果的数量与输入字符串中的 ${paramXXXX} 个片段的数量相同,上述代码都应该工作。

请务必将// Replace with ...后面的代码替换为读取查询结果的代码。

【讨论】:

  • 从数据库中查询替换值。
  • @Frank.Dai 这没什么变化,答案是正确的。它假设你做了类似String[] results = query.getResultArray();
  • 如果 ${param0},${param10}
  • 在这种情况下,只要您有 11 个结果(0 到 10 = 11)就可以正常工作。但是,如果您必须考虑实际上只有两个值并且${paramX} 后面的数字实际上是任意的,那么您将需要更多的逻辑来处理它。我现在就写一个:)
  • @MichaelZiluck 我认为真正的问题(但解释得非常糟糕)是 str 就像你的第二个例子。并且OP需要从中读取数字(第一个0),在数据库中查询值(索引0处的值),然后用值替换字符串。对第二个执行相同操作:读取值 12,查询数据库中的 value12,将字符串 ${param12} 替换为 gueried 值。等等……
【解决方案2】:

这是一种使用匹配器的方法:

String str = "${param0},${param1}, ${param2}";
System.out.println("Matching: "+str);
Pattern regex = Pattern.compile("\\$\\{(\\w+)\\}");
Matcher matcher = regex.matcher(str);
while (matcher.find()){
  System.out.println("found: "+matcher.group());
  str = matcher.replaceFirst("results");
  matcher = regex.matcher(str);
}
System.out.println("Result: "+str);

这不是很有效,但很容易使用。如果您有千兆字节规模的计算,请考虑循环输入字符串并手动比较字符。

更新:

这是一个更好的方法。如果结果包含该模式,则效率更高且不易出现死循环。

String str = "[${param0},${param1}, ${param2}]";
System.out.println("Matching: " + str);
final Pattern regex = Pattern.compile("\\$\\{(\\w+)\\}"); 
final Matcher matcher = regex.matcher(str);
final StringBuilder sb = new StringBuilder(str.length());
int prevMatch = 0;
while (matcher.find()) {
  System.out.println("found: " + matcher.group());
  sb.append(str.substring(prevMatch, matcher.start()));
  sb.append("results");
  prevMatch = matcher.end();
}
sb.append(str.substring(prevMatch, str.length()));
System.out.println("Result: " + sb.toString());

【讨论】:

  • @Socowi 谢谢,反正我不喜欢这个匹配器重建,所以我完全改变了它。
猜你喜欢
  • 2013-06-29
  • 1970-01-01
  • 1970-01-01
  • 2012-09-10
  • 1970-01-01
  • 2021-04-22
  • 2013-02-25
  • 1970-01-01
  • 2011-09-14
相关资源
最近更新 更多