Luigi R. Viggiano Luigi R. Viggiano - 11 months ago 136
Java Question

StrSubstitutor replacement with JRE libraries

At the moment I am using

for doing:

Map m = ...
substitutor = new StrSubstitutor(m);

result = substitutor.replace(input);

Given the fact I want to remove
dependency from my project what would be a working and minimalistic implementation of
using standard JRE libraries?


works like this:

Map map = 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 = "The quick brown fox jumped over the lazy dog."

Answer Source

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) { = map;

    public String replace(String str) {
        Matcher m = p.matcher(str);
        StringBuilder sb = new StringBuilder();
        while (m.find()) {
            String var =;
            String replacement = map.get(var);
            m.appendReplacement(sb, replacement);
        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 {
        if (i < strArray.length) sb.append(strArray[i]);
        return sb.toString();

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.