Java string templatizer / formatter with named arguments

You might also try org.apache.commons.lang3.text.StrSubstitutor if Java 7 is not an option. It does exactly what you want it to do. Whether it’s light-weight might depend on whether you use something else of commons-lang as well.


I recently discovered JUEL which fits the description nicely. It is the expression language taken out of JSP. It claims to be very fast, too.

I'm about to try it out in one of my own projects.

But for a lighter-weight, which is a variant of yours, try this (wrapped in a unit test):

public class TestInterpolation {

    public static class NamedFormatter {
        public final static Pattern pattern = Pattern.compile("#\\{(?<key>.*)}");
        public static String format(final String format, Map<String, ? extends Object> kvs) {
            final StringBuffer buffer = new StringBuffer();
            final Matcher match = pattern.matcher(format);
            while (match.find()) {
                final String key = match.group("key");
                final Object value = kvs.get(key);
                if (value != null)
                    match.appendReplacement(buffer, value.toString());
                else if (kvs.containsKey(key))
                    match.appendReplacement(buffer, "null");
                else
                    match.appendReplacement(buffer, "");
            }
            match.appendTail(buffer);
            return buffer.toString();
        }
    }

    @Test
    public void test() {
        assertEquals("hello world", NamedFormatter.format("hello #{name}", map("name", "world")));
        assertEquals("hello null", NamedFormatter.format("hello #{name}", map("name", null)));
        assertEquals("hello ", NamedFormatter.format("hello #{name}", new HashMap<String, Object>()));
    }

    private Map<String, Object> map(final String key, final Object value) {
        final Map<String, Object> kvs = new HashMap<>();
        kvs.put(key, value);
        return kvs;
    }
}

I'd extend it to add convenience methods to for quick key-value pairs

format(format, key1, value1)
format(format, key1, value1, key2, value2)
format(format, key1, value1, key2, value2, key3, value3)
...

And it shouldn't be too hard to convert from java 7+ to java 6-


Matcher#appendReplacement() would help


StringTemplate may be as light-weight an interpolation engine as you're likely to get, although I don't know how it stacks up resource-wise against things like FreeMarker, Mustache, or Velocity.

Another option might be an EL engine like MVEL, which has a templating engine.