字符串插值替换器,替换字符串中的插值表达式(简单实现,仅用于短文本)

package com.geostar.geoonline.tools.config_write.util;

import lombok.Builder;
import lombok.Getter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 字符串插值替换器,替换字符串中的插值表达式(简单实现,仅用于短文本),如替换字符串“有一个人叫{{name}},他今年{{age}}岁,他在{{company}}上班”中双括号扩起来的内容
 */
@Getter
@Builder
public class StringReplacer {

    /**
     * 差值表达式左侧开始字符串,默认为 "{{"
     */
    private String leftText;

    /**
     * 差值表达式右侧结束字符串,默认为 "}}"
     */
    private String rightText;

    /**
     * 包含插值表达式的文本内容
     */
    private String content;

    /**
     * 严格模式,严格模式时调用 replace 方法 replaceMap 缺少替换参数则抛出异常
     */
    private boolean strict;

    public static void main(String[] args) {
        String content = "有一个人叫{{name}},他今年{{age}}岁,他在{{company}}上班";
        String leftText = "{{";
        String rightText = "}}";
        Map<String, String> replaceMap = new HashMap<>();
        replaceMap.put("name", "王睿");
        replaceMap.put("age", "34");
        replaceMap.put("company", "吉奥时空");
        String text = StringReplacer.builder()
                .content(content)
                .leftText(leftText)
                .rightText(rightText)
                .strict(true)
                .build().replace(replaceMap);
        System.out.println(text);
        System.out.println(StringReplacer.replace(content, leftText, rightText, replaceMap));
    }

    /**
     * 通过map替换
     *
     * @param replaceMap
     * @return
     */
    public String replace(Map<String, String> replaceMap) {
        if (leftText == null) {
            leftText = "{{";
        }
        if (rightText == null) {
            rightText = "}}";
        }
        return replace(content, leftText, rightText, replaceMap, strict);
    }

    public static String replace(String content, Map<String, String> replaceMap) {
        return replace(content, replaceMap, false);
    }

    public static String replace(String content, Map<String, String> replaceMap, boolean strict) {
        return replace(content, "{{", "}}", replaceMap, strict);
    }

    public static String replace(String content, String leftText, String rightText, Map<String, String> replaceMap) {
        return replace(content, leftText, rightText, replaceMap, false);
    }

    public static String replace(String content, String leftText, String rightText, Map<String, String> replaceMap, boolean strict) {
        checkProperties(content, leftText, rightText);
        List<Integer[]> replaceIndexList = getReplaceIndexList(content, leftText, rightText);
        StringBuilder sb = new StringBuilder();
        int endIndex = -1;
        for (int i = 0; i < replaceIndexList.size(); i++) {
            Integer[] integers = replaceIndexList.get(i);
            if (i == 0) {
                sb.append(content.substring(0, integers[0]));
            } else {
                Integer[] preIntegers = replaceIndexList.get(i - 1);
                sb.append(content.substring(preIntegers[1] + rightText.length(), integers[0]));
            }
            String key = content.substring(integers[0] + leftText.length(), integers[1]);
            if (!replaceMap.containsKey(key) || replaceMap.get(key) == null) {
                if (strict) {
                    throw new RuntimeException(String.format("replaceMap 不包含:%s,或其对应值为 null", key));
                } else {
                    sb.append(leftText + key + rightText);
                }
            } else {
                sb.append(replaceMap.get(key));
            }
            endIndex = integers[1];
        }
        sb.append(content.substring(endIndex + rightText.length(), content.length()));
        return sb.toString();
    }

    private static List<Integer[]> getReplaceIndexList(String content, String leftText, String rightText) {
        List<Integer[]> list = new ArrayList<>();
        List<Integer> leftTextIndex = getTextIndex(content, leftText);
        List<Integer> rightTextIndex = getTextIndex(content, rightText);
        int leftIndex = -1;
        int rightIndex = -1;
        for (int i = 0; i < content.length(); i++) {
            if (leftTextIndex.contains(i)) {
                leftIndex = i;
            }
            if (rightTextIndex.contains(i)) {
                rightIndex = i;
            }
            if (leftIndex != -1 && rightIndex != -1) {
                list.add(new Integer[]{leftIndex, rightIndex});
                leftIndex = -1;
                rightIndex = -1;
            }
        }
        return list;
    }

    private static List<Integer> getTextIndex(String content, String subtext) {
        if (!content.contains(subtext)) {
            return new ArrayList<>();
        }
        String[] split = content.split(Pattern.quote(subtext));
        List<Integer> list = new ArrayList<>();
        Integer index = 0;
        for (String s : split) {
            list.add(s.length() + index);
            index += s.length() + subtext.length();
        }
        list.remove(list.size() - 1);
        return list;
    }

    /**
     * 检测配置
     *
     * @param content
     * @param leftText
     * @param rightText
     */
    public static void checkProperties(String content, String leftText, String rightText) {
        if (content == null) {
            throw new RuntimeException("content 为空");
        }
        if (leftText == null || "".equals(leftText.trim()) || leftText.contains(" ")) {
            throw new RuntimeException("leftText 为空或包含空格");
        }
        if (rightText == null || "".equals(rightText.trim()) || rightText.contains(" ")) {
            throw new RuntimeException("rightText 为空或包含空格");
        }
    }

}

 

posted @ 2023-04-21 16:20  Nihaorz  阅读(97)  评论(0)    收藏  举报