java
29 lines · 8 steps
Rendering ${} templates with regex in Java
A small utility that swaps ${key} placeholders for map values, failing loudly on anything missing.
Explained by
highlit
1import java.util.Map;
2import java.util.regex.Matcher;
3import java.util.regex.Pattern;
4
5public final class TemplateRenderer {
6
7 private static final Pattern PLACEHOLDER = Pattern.compile("\\$\\{([a-zA-Z0-9_.]+)\\}");
8
9 private TemplateRenderer() {
10 }
11
12 public static String render(String template, Map<String, ?> values) {
13 Matcher matcher = PLACEHOLDER.matcher(template);
14 StringBuilder out = new StringBuilder();
15
16 while (matcher.find()) {
17 String key = matcher.group(1);
18 if (!values.containsKey(key)) {
19 throw new IllegalArgumentException("Missing value for placeholder: " + key);
20 }
21 Object value = values.get(key);
22 String replacement = value == null ? "" : value.toString();
23 matcher.appendReplacement(out, Matcher.quoteReplacement(replacement));
24 }
25
26 matcher.appendTail(out);
27 return out.toString();
28 }
29}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Compiling a Pattern once as a static field avoids rebuilding it on every render call.
- 2The appendReplacement/appendTail pair lets you rewrite matches while copying untouched text verbatim.
- 3quoteReplacement neutralizes $ and backslash in substituted values so user data can't corrupt the output.
Related explainers
ruby
class UserAgentParser BROWSERS = [ [/Edg\/([\d.]+)/, "Edge"], [/OPR\/([\d.]+)/, "Opera"],
Parsing user-agent strings in Ruby
regex
pattern-matching
lookup-tables
Intermediate
8 steps
java
@Component @Converter public class EncryptedStringConverter implements AttributeConverter<String, String> {
Transparent column encryption in Spring & JPA
encryption
aes-gcm
jpa-converter
Advanced
10 steps
java
package com.acme.billing.config; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties;
Feature-flagged beans with Spring @ConditionalOnProperty
feature-flags
conditional-beans
strategy-pattern
Intermediate
5 steps
java
public static Map<String, String> parseCookieHeader(String header) { Map<String, String> cookies = new LinkedHashMap<>(); if (header == null || header.isBlank()) { return cookies;
Parsing an HTTP Cookie header in Java
string-parsing
http
url-decoding
Intermediate
6 steps
java
public class TimedSocketReader { private static final int READ_TIMEOUT_MS = 5_000; private static final int CONNECT_TIMEOUT_MS = 3_000;
Reading a socket with connect and read timeouts
sockets
timeouts
io
Intermediate
8 steps
go
package middleware import ( "net/http"
Per-plan export limits in Gin middleware
middleware
rate-limiting
authorization
Intermediate
7 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/rendering-templates-with-regex-in-java-explained-java-142f/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.