Repeated execution of replaceAll , i.e. for each variable variable, it can become quite expensive, especially as the number of variables increases. This does not become more efficient when using the Stream API. The regex package contains the necessary building blocks to make this more efficient:
public static String replaceAll(String template, Map<String,String> variables) { String pattern = variables.keySet().stream() .map(Pattern::quote) .collect(Collectors.joining("|", "\\$\\{(", ")\\}")); Matcher m = Pattern.compile(pattern).matcher(template); if(!m.find()) { return template; } StringBuffer sb = new StringBuffer(); do { m.appendReplacement(sb, Matcher.quoteReplacement(variables.get(m.group(1)))); } while(m.find()); m.appendTail(sb); return sb.toString(); }
If you perform the operation with the same Map very often, you might consider saving the result of Pattern.compile(pattern) , since it is immutable and securely shared.
On the other hand, if you often use this operation with different cards, it is possible that a common template will be used instead, in combination with processing the possibility that a particular variable is not on the map. Adds the ability to report the appearance of the template ${β¦} with an unknown variable:
private static Pattern VARIABLE = Pattern.compile("\\$\\{([^}]*)\\}"); public static String replaceAll(String template, Map<String,String> variables) { Matcher m = VARIABLE.matcher(template); if(!m.find()) return template; StringBuffer sb = new StringBuffer(); do { m.appendReplacement(sb, Matcher.quoteReplacement(variables.getOrDefault(m.group(1), m.group(0)))); } while(m.find()); m.appendTail(sb); return sb.toString(); }
m.group(0) is an actual match, so using it as a falloff for a replacement string sets the original behavior to not replace ${β¦} occurrences when the key is not on the map. As said, alternative behaviors are possible, such as reporting a missing key or using other feedback text.
source share