使用JRE库替换StrSubstitutor [英] StrSubstitutor replacement with JRE libraries
问题描述
目前我正在使用 org.apache.commons.lang.text.StrSubstitutor
进行操作:
At the moment I am using org.apache.commons.lang.text.StrSubstitutor
for doing:
Map m = ...
substitutor = new StrSubstitutor(m);
result = substitutor.replace(input);
鉴于我想删除 commons-lang
依赖于我的项目使用标准JRE库的 StrSubstitutor
的工作和简约实现是什么?
Given the fact I want to remove commons-lang
dependency from my project what would be a working and minimalistic implementation of StrSubstitutor
using standard JRE libraries?
注意:
StrSubstitutor
的工作原理如下:
Map map = new HashMap();
map.put("animal", "quick brown fox");
map.put("target", "lazy dog");
StrSubstitutor sub = new StrSubstitutor(map);
String resolvedString = sub.replace("The ${animal} jumped over the ${target}.");
yielding resolvedString =快速的棕色狐狸跳过懒狗。
yielding resolvedString = "The quick brown fox jumped over the lazy dog."
推荐答案
如果性能不是优先级,则可以使用 appendReplacement
匹配器
类的方法:
If performance is not a priority, you can use the appendReplacement
method of the Matcher
class:
public class StrSubstitutor {
private Map<String, String> map;
private static final Pattern p = Pattern.compile("\\$\\{(.+?)\\}");
public StrSubstitutor(Map<String, String> map) {
this.map = map;
}
public String replace(String str) {
Matcher m = p.matcher(str);
StringBuilder sb = new StringBuilder();
while (m.find()) {
String var = m.group(1);
String replacement = map.get(var);
m.appendReplacement(sb, replacement);
}
m.appendTail(sb);
return sb.toString();
}
}
性能更高但更丑陋的版本,只是为了好玩: )
A more performant but uglier version, just for fun :)
public String replace(String str) {
StringBuilder sb = new StringBuilder();
char[] strArray = str.toCharArray();
int i = 0;
while (i < strArray.length - 1) {
if (strArray[i] == '$' && strArray[i + 1] == '{') {
i = i + 2;
int begin = i;
while (strArray[i] != '}') ++i;
sb.append(map.get(str.substring(begin, i++)));
} else {
sb.append(strArray[i]);
++i;
}
}
if (i < strArray.length) sb.append(strArray[i]);
return sb.toString();
}
它的速度是正则表达式的2倍,比apache的速度快3倍根据我的测试版本。因此,正常的正则表达式实际上比apache版本更优化。当然通常不值得。只是为了好玩,让我知道你是否可以让它更优化。
It's about 2x as fast as the regex version and 3x faster than the apache commons version as per my tests. So the normal regex stuff is actually more optimized than the apache version. Usually not worth it of course. Just for fun though, let me know if you can make it more optimized.
编辑:正如@kmek指出的那样,有一个警告。 Apache版本将过渡解决。例如,如果 $ {animal}
映射到 $ {dog}
和 dog
映射到 Golden Retriever
,apache版本会将 $ {animal}
映射到Golden Retriever。正如我所说,你应该尽可能使用库。如果您有一个不允许使用库的特殊约束,则仅使用上述解决方案。
Edit: As @kmek points out, there is a caveat. Apache version will resolve transitively. e.g, If ${animal}
maps to ${dog}
and dog
maps to Golden Retriever
, apache version will map ${animal}
to Golden Retriever. As I said, you should use libraries as far as possible. The above solution is only to be used if you have a special constraint which does not allow you to use a library.
这篇关于使用JRE库替换StrSubstitutor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!