给定以下变量
templateText = "Hi ${name}";
variables.put("name", "Joe");
我想使用以下代码将占位符${name}替换为值“joe”(这不起作用)
variables.keySet().forEach(k -> templateText.replaceAll("\\${\\{"+ k +"\\}" variables.get(k)));
但是,如果我按照“老式”的方式来做,一切都运行得很完美:
for (Entry<String, String> entry : variables.entrySet()){
String regex = "\\$\\{" + entry.getKey() + "\\}";
templateText = templateText.replaceAll(regex, entry.getValue());
}
)我一定漏了点什么
实现这一点的正确方式在Java 8中没有改变,它基于appendreplacement()
/appendtail()
:
Pattern variablePattern = Pattern.compile("\\$\\{(.+?)\\}");
Matcher matcher = variablePattern.matcher(templateText);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(result, variables.get(matcher.group(1)));
}
matcher.appendTail(result);
System.out.println(result);
请注意,正如drrob在注释中提到的,appendreplacement()
的替换字符串可能包含使用$
符号的组引用,并使用\
进行转义。如果不希望这样做,或者替换字符串可能包含这些字符,则应使用matcher.quoterePlacement()
转义它们。
如果您想要一个更像Java-8风格的版本,可以将搜索并替换锅炉板代码提取到一个采用替换函数
的通用方法中:
private static StringBuffer replaceAll(String templateText, Pattern pattern,
Function<Matcher, String> replacer) {
Matcher matcher = pattern.matcher(templateText);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(result, replacer.apply(matcher));
}
matcher.appendTail(result);
return result;
}
并将其用作
Pattern variablePattern = Pattern.compile("\\$\\{(.+?)\\}");
StringBuffer result = replaceAll(templateText, variablePattern,
m -> variables.get(m.group(1)));
请注意,使用patter
作为参数(而不是string
)允许将其存储为常量,而不是每次都重新编译它。
与上面关于$
和\
的说明相同-如果您不希望ReplaceAll()
函数处理QuoterePlace()
方法,您可能希望在ReplaceAll()
方法中强制执行QuoterePlace()
。
Java 9引入了matcher.replaceAll(Function)
,它基本上实现了与上面的函数版本相同的东西。更多细节见杰西·格利克的回答。
您还可以使用stream.reduce(标识、累加器、组合器)。
identity
是约简函数的初始值,约简函数是accumulator
。
累加器
将标识
还原为结果
,如果流是顺序的,则该标识
是下一次还原的标识
。
这个函数永远不要在顺序流中调用。它在并行流中从标识
和结果
中计算下一个标识
。
BinaryOperator<String> combinerNeverBeCalledInSequentiallyStream=(identity,t) -> {
throw new IllegalStateException("Can't be used in parallel stream");
};
String result = variables.entrySet().stream()
.reduce(templateText
, (it, var) -> it.replaceAll(format("\\$\\{%s\\}", var.getKey())
, var.getValue())
, combinerNeverBeCalledInSequentiallyStream);
问题内容: 给定以下变量 我想使用以下代码将占位符$ {name}替换为值“ Joe”(不起作用) 但是,如果我采用“旧式”方式,则一切都将正常运行: 我肯定在这里想念的东西:) 问题答案: 您还可以使用Stream.reduce(identity,accumulator,combiner)。 身份 是减少函数的初始值。 累加器 减少到,如果流是 顺序的 ,这是下一个减少的条件。 合路器 永远不要
null 我读过PDO的书。如何使用MySQL或MSSQL将代码更新为PDO?
我用Mockito写UT,我想替换我的mock函数(哪个DB选择操作) 使用我在测试类中编写的新函数(使用map模拟数据库选择); 我想用正确的键输入返回正确的值 我试图这样做使用ArgumentCaptor如下,但它没有工作,因为我想 我想当调用dataBaseSelect.selectDataFromDB时,它将被模拟,然后从MapSelect.selectDataFromMap返回结果,参数
函数名称:字符串替换 函数功能:字符串替换 函数方法 str,num = string.gsub(s,pattern,repl,n) 参数 类型 必填 说明 s string/table/number 是 原字符串 pattern string/table/number 是 待查找的字符串或模式匹配 repl string/table/number 是 待替换的字符串 n number 否 替换次
问题内容: 我在Java 8映射操作中传递了一个Function,Intellij告诉我可以将其替换为lambda表达式。但是我不知道如何在不创建中间对象结构的情况下做到这一点。 这是我的工作: 我认为Intellij建议我这样做: 我不知道一种干净的方法来获取在匿名函数中检索到的objectType.getTempUrl()。getFullUrl()部分,有什么建议吗? 问题答案: 你总是可以写
我正在尝试将登录用户的详细信息提供给我的应用程序。我有以下代码在Angular 5中工作,但在Angular 6中不工作,因为. share()函数在rxjs 6中丢失 我需要这个吗。share()函数?关于rxjs 6的更改,我的代码看起来还好吗?