Java-custom placeholder replacement tool class
MessageFormat: Provides a way to generate concatenated messages in a language-neutral way. Use it to construct messages that are displayed to the end user.
Matcher: Matcher parser performs matching operations on character sequences based on Pattern regular expressions.
Implementation code
maven dependencies
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.12.0</version> </dependency>
Tools
package com.tangsm.util; import org.apache.commons.lang3.StringUtils; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.text.MessageFormat; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Custom placeholder replacement tool class * * @author tangyb */ public class PlaceholderUtils {<!-- --> /** * Placeholder regular expression: $ + curly braces * <p>Placeholder example: {<!-- -->@code ${<!-- -->xxx}}</p> */ public static final Pattern PATTERN_BRACE = Pattern.compile("\$\{(.*?)}"); /** * Placeholder regular expression: $ + angle brackets * <p>Placeholder example: {<!-- -->@code $<xxx>}</p> */ public static final Pattern PATTERN_ANGLE = Pattern.compile("\$<(.*?)>"); /** * matcher */ private static Matcher matcher; /** * Replace string placeholders, variable parameters, and use the order {<!-- -->0}{<!-- -->1}...{<!-- -->*} in the string subscript, indicating placeholder * * @param source The string to be matched, example: "Name: {0}, Age: {1}, School: {2}" * @param params variable parameters, dynamic parameters * @return replaced string */ public static String replaceWithVarargs(String source, Object... params) {<!-- --> return MessageFormat.format(source, params); } /** * Replace string placeholders, Map parameters, use ${<!-- -->key} in strings to represent placeholders * * @param source The string to be matched, example: "Name: ${name}, age: ${age}, school: ${school}" * @param params parameter set, Map type * @return the replaced string */ public static String replaceWithMap(String source, Map<String, Object> params) {<!-- --> if (StringUtils.isBlank(source) || CollectionUtils.isEmpty(params)) {<!-- --> return source; } String targetString = source; matcher = PATTERN_BRACE.matcher(source); while (matcher.find()) {<!-- --> try {<!-- --> String key = matcher.group(); //If the placeholder is {<!-- -->} here is key.substring(1, key.length() - 1).trim() String keyClone = key.substring(2, key.length() - 1).trim(); Object value = params.get(keyClone); if (value != null) {<!-- --> targetString = targetString.replace(key, value.toString()); } } catch (Exception e) {<!-- --> throw new RuntimeException("String formatter failed", e); } } return targetString; } /** * Replace the string placeholder, POJO pass parameters, use ${<!-- -->key} in the string to represent the placeholder * * <p>Note: Use reflection to automatically obtain object property values (must have a get method)</p> * * @param source The string to be matched * @param params parameter entity * @return the replaced string */ public static String replaceWithObject(String source, Object params) {<!-- --> if (StringUtils.isBlank(source) || ObjectUtils.isEmpty(params)) {<!-- --> return source; } String targetString = source; PropertyDescriptor pd; Method getMethod; // Match the content in ${<!-- -->} including parentheses matcher = PATTERN_BRACE.matcher(source); while (matcher.find()) {<!-- --> String key = matcher.group(); String holderName = key.substring(2, key.length() - 1).trim(); try {<!-- --> pd = new PropertyDescriptor(holderName, params. getClass()); // Get the get method getMethod = pd.getReadMethod(); Object value = getMethod.invoke(params); if (value != null) {<!-- --> targetString = targetString.replace(key, value.toString()); } } catch (Exception e) {<!-- --> throw new RuntimeException("String formatter failed", e); } } return targetString; } /** * Get the placeholder keys in String * <p>Example: name: ${<!-- -->name}, age: ${<!-- -->age}, school: ${<!-- -->school}, return: Set[name, age, school]</p> * * @param source source string * @param pattern regular expression, pattern example: <pre> {<!-- -->@code * // Angle brackets: <placeHolder> is represented as a placeholder * Pattern pattern = Pattern.compile("\$<(.*?)>"); * * // Braces: {<!-- -->placeHolder} is represented as a placeholder, and {<!-- -->} is used as a placeholder in the above example * Pattern pattern = Pattern.compile("\$\{(.*?)}"); * }
* @return Set collection
*/
public static Set
Set
// If the parameters are incorrect, an empty collection will be returned.
if (StringUtils.isBlank(source) || ObjectUtils.isEmpty(pattern)) {
return placeHolderSet;
}
// Initial matcher based on regular expression
matcher = pattern.matcher(source);
while (matcher.find()) {
//Example: {name}
String key = matcher.group();
//Example: name
String placeHolder = key.substring(2, key.length() – 1).trim();
placeHolderSet.add(placeHolder);
}
return placeHolderSet;
}
}
entity
package com.tangsm.domain;
/**
* User Info
*
* @author tangsm
*/
public class UserInfo {
/**
* Name
*/
private String name;
/**
* age
*/
private Integer age;
/**
* School
*/
private String school;
/**
* No parameter construction
*/
public UserInfo() {
}
/**
* Full parameter structure
*
* @param name name
* @param age age
* @param school school
*/
public UserInfo(String name, Integer age, String school) {
this.name = name;
this.age = age;
this.school = school;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSchool() {
return to school;
}
public void setSchool(String school) {
this.school = school;
}
}
test class
package com.tangsm.util;
import com.tangsm.domain.UserInfo;
import com.tangsm.util.PlaceholderUtils;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
/**
* Custom placeholder replacement tool class test class
*
* @author tangsm
*/
public class PlaceholderUtilsTest {
private final Logger log = LoggerFactory. getLogger(PlaceholderUtilsTest. class);
private static final String SOURCE0 = “Name: {0}, Age: {1}, School: {2}”;
private static final String SOURCE1 = “Name: ${name}, age: ${age}, school: ${school}”;
private static final String SOURCE2 = “Name: $
/**
* Replace string placeholders, dynamic parameters, use {0}{1}…{*} order in the string mark, indicating placeholder, test method
*/
@Test
void replaceWithVarargs() {
log.info(“replaceWithVarargs, processing result: {}”, PlaceholderUtils.replaceWithVarargs(SOURCE0, “Xiaomei”, 18, “Female High School”));
}
/**
* Replace string placeholders, map parameters, use ${key} in strings to represent placeholders, test methods
*/
@Test
void replaceWithMap() {
HashMap
params.put(“name”, “Xiaomei”);
params.put(“age”, 18);
params.put(“school”, “Female Senior High School”);
log.info(“replaceWithMap, processing result: {}”, PlaceholderUtils.replaceWithMap(SOURCE1, params));
}
/**
* Replace the string placeholder, POJO parameter passing, use ${key} in the string to represent the placeholder, test method
*/
@Test
void replaceWithObject() {
UserInfo userInfo = new UserInfo(“Xiaomei”, 18, “Female High School No. 1”);
log.info(“replaceWithObject, processing result: {}”, PlaceholderUtils.replaceWithObject(SOURCE1, userInfo));
}
/**
* Get the placeholder keys in String
*/
@Test
void getPlaceholderKeys() {
log.info(“getPlaceholderKeys-PATTERN_BRACE, processing result: {}”, PlaceholderUtils.getPlaceholderKeys(SOURCE1, PlaceholderUtils.PATTERN_BRACE));
log.info(“getPlaceholderKeys-PATTERN_ANGLE, processing result: {}”, PlaceholderUtils.getPlaceholderKeys(SOURCE2, PlaceholderUtils.PATTERN_ANGLE));
}
}
Test Results
PlaceholderUtilsTest – replaceWithObject, processing results: Name: Xiaomei, Age: 18, School: Girls’ High School No. 1
PlaceholderUtilsTest – getPlaceholderKeys-PATTERN_BRACE, processing result: [school, name, age]
PlaceholderUtilsTest – getPlaceholderKeys-PATTERN_ANGLE, processing result: [school, name, age]
PlaceholderUtilsTest – replaceWithVarargs, processing results: Name: Xiaomei, Age: 18, School: Girls’ High School No. 1
PlaceholderUtilsTest – replaceWithMap, processing results: Name: Xiaomei, Age: 18, School: Girls’ High School No. 1