【占位符替换】替换String中的占位符标志位{placeholder}

概述

占位符替换, 占位符表示为:{placeholder};

示例:替换如下{xxx}占位符中的内容

"名字:{name},年龄:{age},学校:{school}"

提供了两种不同的替换方式:

  1. 使用Map对占位符的内容进行替换;
  2. 使用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
原文地址:https://www.cnblogs.com/ssslinppp/p/7921541.html