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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With