Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java EE method to replace dollar sign ($) variables with custom string

Is there a pre-written method to replace dollar-sign name variables in a string with a predefined constant?

For example, the following code :

Map<String, Object> myVars = new TreeMap<String, Object>();
String str = "The current year is ${currentYear}.";
myVars.put("currentYear", "2014");
System.out.println(Replacer.replaceVars(str, myVars));

... would have this output:

The current year is 2014.
like image 941
patstuart Avatar asked Jun 25 '26 05:06

patstuart


2 Answers

I am not aware of any standard Java class which would support this behaviour but writing your tool wouldn't be so hard. Here is example of such solution:

class Replacer {
    private static Pattern pattern = Pattern.compile("\\$\\{(?<key>[^}]*)\\}");

    public static String replaceVars(String format, Map<String, ?> map) {
        StringBuffer sb = new StringBuffer();
        Matcher m = pattern.matcher(format);
        while (m.find()) {
            String key = m.group("key");
            if (map.containsKey(key)) {//replace if founded key exists in map
                m.appendReplacement(sb, map.get(key).toString());
            } else {//do not replace, or to be precise replace with same value
                m.appendReplacement(sb, m.group());
            }
        }
        m.appendTail(sb);

        return sb.toString();
    }
}

We could take advantage of default method getOrDefault introduced in Java 8 to Map interface and replace

while (m.find()) {
    String key = m.group("key");
    if (map.containsKey(key)) {//replace if founded key exists in map
        m.appendReplacement(sb, map.get(key).toString());
    } else {//do not replace, or to be precise replace with same value
        m.appendReplacement(sb, m.group());
    }
}
m.appendTail(sb);

with

while (m.find()) 
    m.appendReplacement(sb, map.getOrDefault(m.group("key"), m.group()));
m.appendTail(sb);

But to be able to use this method we first would need to specify type of value in map - in other words we would need to change type of accepted Map from Map<String, ?> map to type like Map<String, String> map.

like image 196
Pshemo Avatar answered Jun 27 '26 19:06

Pshemo


Spring does this too if you need to support more advanced use cases. I was able to utilize code from the following class for my use cases. See the parseStringValue method.

https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java

In your case, you need to pass in a PlaceholderResolver that uses your Map to resolve the placeholder.

like image 31
user1366367 Avatar answered Jun 27 '26 19:06

user1366367



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!