概述
占位符替換, 占位符表示為:{placeholder}
;
示例:替換如下{xxx}占位符中的內容
"名字:{name},年齡:{age},學校:{school}"
提供了兩種不同的替換方式:
- 使用Map對占位符的內容進行替換;
- 使用POJO對象,對占位符中的內容替換;
代碼
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Desc: 占位符替換, 占位符表示為:{@code {placeholder}};
* <p>
* 示例:替換如下{xxx}占位符中的內容
* <pre>"名字:{name},年齡:{age},學校:{school}"</pre>
*/
public class PlaceHolderReplaceUtils {
private static final Pattern pattern = Pattern.compile("\\{(.*?)\\}");
private static Matcher matcher;
/**
* 替換字符串占位符, 字符串中使用{key}表示占位符
*
* @param sourceString 需要匹配的字符串,示例:"名字:{name},年齡:{age},學校:{school}";
* @param param 參數集,Map類型
* @return
*/
public static String replaceWithMap(String sourceString, Map<String, Object> param) {
if (Strings.isNullOrEmpty(sourceString) || CollectionUtils.isEmpty(param)) {
return sourceString;
}
String targetString = sourceString;
matcher = pattern.matcher(sourceString);
while (matcher.find()) {
try {
String key = matcher.group();
String keyclone = key.substring(1, key.length() - 1).trim();
Object value = param.get(keyclone);
if (value != null) {
targetString = targetString.replace(key, value.toString());
}
} catch (Exception e) {
throw new RuntimeException("String formatter failed", e);
}
}
return targetString;
}
/**
* 替換字符串占位符, 字符串中使用{key}表示占位符
* <p>
* 利用反射 自動獲取對象屬性值 (必須有get方法)
*
* @param sourceString 需要匹配的字符串
* @param param 參數集
* @return
*/
public static String replaceWithObject(String sourceString, Object param) {
if (Strings.isNullOrEmpty(sourceString) || ObjectUtils.isEmpty(param)) {
return sourceString;
}
String targetString = sourceString;
PropertyDescriptor pd;
Method getMethod;
// 匹配{}中間的內容 包括括號
matcher = pattern.matcher(sourceString);
while (matcher.find()) {
String key = matcher.group();
String holderName = key.substring(1, key.length() - 1).trim();
try {
pd = new PropertyDescriptor(holderName, param.getClass());
getMethod = pd.getReadMethod(); // 獲得get方法
Object value = getMethod.invoke(param);
if (value != null) {
targetString = targetString.replace(key, value.toString());
}
} catch (Exception e) {
throw new RuntimeException("String formatter failed", e);
}
}
return targetString;
}
/**
* 查找String中的占位符keys;<br/>
* 示例: "名字:{name},年齡:{age},學校:{school}", 則返回:Set[name,age,school]
* <p>
* pattern示例:
* <pre> {@code
* // 尖括號:<placeHolder> 表示為占位符
* Pattern pattern = Pattern.compile("\\<(.*?)\\>");
*
* // 大括號:{placeHolder} 表示為占位符, 上面的示例中就使用{}作為占位符
* Pattern pattern = Pattern.compile("\\{(.*?)\\}");
* }
* </pre>
*
* @param sourceString
* @param pattern
* @return
*/
public static Set<String> findPlaceHolderKeys(String sourceString, Pattern pattern) {
Set<String> placeHolderSet = Sets.newConcurrentHashSet();
if (Strings.isNullOrEmpty(sourceString) || ObjectUtils.isEmpty(pattern)) {
return placeHolderSet;
}
String targetString = sourceString;
matcher = pattern.matcher(sourceString);
while (matcher.find()) {
String key = matcher.group(); //示例: {name}
String placeHolder = key.substring(1, key.length() - 1).trim(); //示例: name
placeHolderSet.add(placeHolder);
}
return placeHolderSet;
}
}
測試代碼
package com.chinamobile.epic.regex;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.junit.Test;
import java.util.Map;
public class PlaceHolderReplaceUtilsTest {
@Test
public void replaceWithMap() throws Exception {
String sourStr = "名字:{name},{name},年齡:{age},{school},學校:{school}";
Map<String, Object> map = Maps.newHashMap();
map.put("name", "Tom");
map.put("age", 27);
map.put("school", "Beijing");
String tagerStr = PlaceHolderReplaceUtils.replaceWithMap(sourStr, map);
System.out.println(tagerStr);
}
@Test
public void replaceWithObject() throws Exception {
String sourStr = "名字:{name},{name},年齡:{age},{school},學校:{school}";
Person person = new Person("ZhangSan", "Suzhou", 45);
String tagerStr = PlaceHolderReplaceUtils.replaceWithObject(sourStr, person);
System.out.println(tagerStr);
}
@Data
@AllArgsConstructor
public static class Person {
private String name;
private String school;
private int age;
}
}
結果輸出
名字:ZhangSan,ZhangSan,年齡:45,Suzhou,學校:Suzhou
名字:Tom,Tom,年齡:27,Beijing,學校:Beijing