概述
技术重点
- MessageFormat:提供了一种以语言中立的方式产生串联消息的方法。使用它可以构造为最终用户显示的消息。
- Matcher:Matcher解析器,根据Pattern正则表达式,对字符序列执行匹配操作。
实现代码
maven依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
工具类
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;
/**
* 自定义占位符替换工具类
*
* @author tangyb
*/
public class PlaceholderUtils {
/**
* 占位符正则表达式:$+花括号
* <p>占位符示例:{@code ${xxx}}</p>
*/
public static final Pattern PATTERN_BRACE = Pattern.compile("\$\{(.*?)}");
/**
* 占位符正则表达式:$+尖括号
* <p>占位符示例:{@code $<xxx>}</p>
*/
public static final Pattern PATTERN_ANGLE = Pattern.compile("\$<(.*?)>");
/**
* 匹配器
*/
private static Matcher matcher;
/**
* 替换字符串占位符,可变参数,字符串中使用{0}{1}...{*}顺序下标,表示占位符
*
* @param source 需要匹配的字符串,示例:"名字:{0},年龄:{1},学校:{2}"
* @param params 可变参数,动态参数
* @return 替换后的字符串
*/
public static String replaceWithVarargs(String source, Object... params) {
return MessageFormat.format(source, params);
}
/**
* 替换字符串占位符,Map传参,字符串中使用${key}表示占位符
*
* @param source 需要匹配的字符串,示例:"名字:${name},年龄:${age},学校:${school}"
* @param params 参数集,Map类型
* @return 替换后的字符串
*/
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();
//如果占位符是{} 这里就是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("字符串格式化程序失败", e);
}
}
return targetString;
}
/**
* 替换字符串占位符,POJO传参,字符串中使用${key}表示占位符
*
* <p>注:利用反射,自动获取对象属性值 (必须有get方法) </p>
*
* @param source 需要匹配的字符串
* @param params 参数实体
* @return 替换后的字符串
*/
public static String replaceWithObject(String source, Object params) {
if (StringUtils.isBlank(source) || ObjectUtils.isEmpty(params)) {
return source;
}
String targetString = source;
PropertyDescriptor pd;
Method getMethod;
// 匹配${}中间的内容 包括括号
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方法
getMethod = pd.getReadMethod();
Object value = getMethod.invoke(params);
if (value != null) {
targetString = targetString.replace(key, value.toString());
}
} catch (Exception e) {
throw new RuntimeException("字符串格式化程序失败", e);
}
}
return targetString;
}
/**
* 获取String中的占位符keys
* <p>示例:名字:${name},年龄:${age},学校:${school},返回:Set[name,age,school]</p>
*
* @param source 源字符串
* @param pattern 正则表达式,pattern示例:<pre> {@code
* // 尖括号:<placeHolder> 表示为占位符
* Pattern pattern = Pattern.compile("\$<(.*?)>");
*
* // 大括号:{placeHolder} 表示为占位符, 上面的示例中就使用{}作为占位符
* Pattern pattern = Pattern.compile("\$\{(.*?)}");
* } </pre>
* @return Set集合
*/
public static Set<String> getPlaceholderKeys(String source, Pattern pattern) {
Set<String> placeHolderSet = new HashSet<>();
// 参数有误返回空集合
if (StringUtils.isBlank(source) || ObjectUtils.isEmpty(pattern)) {
return placeHolderSet;
}
// 根据正则表达式初始匹配器
matcher = pattern.matcher(source);
while (matcher.find()) {
//示例: {name}
String key = matcher.group();
//示例: name
String placeHolder = key.substring(2, key.length() - 1).trim();
placeHolderSet.add(placeHolder);
}
return placeHolderSet;
}
}
实体
package com.tangsm.domain;
/**
* 用户信息
*
* @author tangsm
*/
public class UserInfo {
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 学校
*/
private String school;
/**
* 无参构造
*/
public UserInfo() {
}
/**
* 全参构造
*
* @param name 名称
* @param age 年龄
* @param 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 school;
}
public void setSchool(String school) {
this.school = school;
}
}
测试类
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;
/**
* 自定义占位符替换工具类测试类
*
* @author tangsm
*/
public class PlaceholderUtilsTest {
private final Logger log = LoggerFactory.getLogger(PlaceholderUtilsTest.class);
private static final String SOURCE0 = "名字:{0},年龄:{1},学校:{2}";
private static final String SOURCE1 = "名字:${name},年龄:${age},学校:${school}";
private static final String SOURCE2 = "名字:$<name>,年龄:$<age>,学校:$<school>";
/**
* 替换字符串占位符,动态参数,字符串中使用{0}{1}...{*}顺序下标,表示占位符,测试方法
*/
@Test
void replaceWithVarargs() {
log.info("replaceWithVarargs,处理结果:{}", PlaceholderUtils.replaceWithVarargs(SOURCE0, "小美", 18, "女高一中"));
}
/**
* 替换字符串占位符,Map传参,字符串中使用${key}表示占位符,测试方法
*/
@Test
void replaceWithMap() {
HashMap<String, Object> params = new HashMap<>();
params.put("name", "小美");
params.put("age", 18);
params.put("school", "女高一中");
log.info("replaceWithMap,处理结果:{}", PlaceholderUtils.replaceWithMap(SOURCE1, params));
}
/**
* 替换字符串占位符,POJO传参,字符串中使用${key}表示占位符,测试方法
*/
@Test
void replaceWithObject() {
UserInfo userInfo = new UserInfo("小美", 18, "女高一中");
log.info("replaceWithObject,处理结果:{}", PlaceholderUtils.replaceWithObject(SOURCE1, userInfo));
}
/**
* 获取String中的占位符keys
*/
@Test
void getPlaceholderKeys() {
log.info("getPlaceholderKeys-PATTERN_BRACE,处理结果:{}", PlaceholderUtils.getPlaceholderKeys(SOURCE1, PlaceholderUtils.PATTERN_BRACE));
log.info("getPlaceholderKeys-PATTERN_ANGLE,处理结果:{}", PlaceholderUtils.getPlaceholderKeys(SOURCE2, PlaceholderUtils.PATTERN_ANGLE));
}
}
测试结果
PlaceholderUtilsTest - replaceWithObject,处理结果:名字:小美,年龄:18,学校:女高一中
PlaceholderUtilsTest - getPlaceholderKeys-PATTERN_BRACE,处理结果:[school, name, age]
PlaceholderUtilsTest - getPlaceholderKeys-PATTERN_ANGLE,处理结果:[school, name, age]
PlaceholderUtilsTest - replaceWithVarargs,处理结果:名字:小美,年龄:18,学校:女高一中
PlaceholderUtilsTest - replaceWithMap,处理结果:名字:小美,年龄:18,学校:女高一中
参考
-
Java基础------动态参数(可变参数,例如:Object… params)
-
Java 解决占位符${xx}问题
-
替换String中的占位符标志位{placeholder}
-
字符串中{ }占位符替换方面的问题
-
Java 模板变量替换(字符串、占位符替换)
最后
以上就是温暖哈密瓜为你收集整理的Java-自定义占位符替换工具类的全部内容,希望文章能够帮你解决Java-自定义占位符替换工具类所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复