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 为空或包含空格");
}
}
}