From 175fbf93a2166aceb7aba1b4efeee1de3213163c Mon Sep 17 00:00:00 2001
From: yuejiajun <1530620364@qq.com>
Date: Sun, 28 Sep 2025 12:01:37 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=96=B9=E6=B3=95=E8=A7=A3?=
=?UTF-8?q?=E6=9E=90=E4=B8=BA=20{{key}}=20=E6=A0=BC=E5=BC=8F=E7=9A=84=20js?=
=?UTF-8?q?on?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../demo/draft/demo043/util/FormatUtil.java | 447 ++++++++++++++++--
1 file changed, 407 insertions(+), 40 deletions(-)
diff --git a/src/main/java/com/example/demo/draft/demo043/util/FormatUtil.java b/src/main/java/com/example/demo/draft/demo043/util/FormatUtil.java
index 6bffe1d..186bdb3 100644
--- a/src/main/java/com/example/demo/draft/demo043/util/FormatUtil.java
+++ b/src/main/java/com/example/demo/draft/demo043/util/FormatUtil.java
@@ -1,8 +1,14 @@
package com.example.demo.draft.demo043.util;
+import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Map;
+import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -72,6 +78,7 @@ import java.util.regex.Pattern;
*
创建时间: 2024年
* 维护者: demo043项目组
*/
+@Slf4j
public class FormatUtil {
/**
@@ -1371,17 +1378,234 @@ public class FormatUtil {
}
/**
- * 偷梁换柱 - 支持正则表达式和多种替换选项
- * @param source 源字符串
- * @param replacementMap 替换映射关系
- * @return 替换后的字符串
+ * 字符串批量替换工具方法
+ *
+ * 该方法提供强大的字符串替换功能,支持正则表达式和普通字符串替换,
+ * 可灵活控制大小写敏感和整词匹配等选项。方法名"偷梁换柱"形象地描述了替换功能。
+ *
+ * 功能特性:
+ *
+ * - 支持正则表达式替换和普通字符串替换
+ * - 可配置大小写敏感匹配
+ * - 支持整词匹配(word boundary)
+ * - 提供正则表达式错误降级处理
+ * - 支持批量替换操作
+ *
+ *
+ * @param source 源字符串,如果为null则直接返回null
+ * @param replacementMap 替换映射表,Key为要查找的模式(正则表达式或普通字符串),
+ * Value为替换内容。如果为null或空则返回原字符串
+ * @param caseSensitive 是否大小写敏感
+ * true: 区分大小写,false: 不区分大小写
+ * @param wholeWord 是否整词匹配
+ * true: 只匹配完整单词,false: 匹配任意位置
+ * @param useRegex 是否使用正则表达式
+ * true: 将key作为正则表达式处理,false: 作为普通字符串处理
+ * @return 替换后的字符串,如果源字符串或替换映射表为null/空则返回原字符串
+ * @throws IllegalArgumentException 当replacementMap包含null键或值时抛出
*/
- public static String stealBeamsAndReplacePillars(String source, Map replacementMap) {
- return stealBeamsAndReplacePillars(source, replacementMap, false, false);
+ public static String stealBeamsAndReplacePillars(String source, Map replacementMap,
+ boolean caseSensitive, boolean wholeWord, boolean useRegex) {
+ // 参数校验:如果源字符串或替换映射表为空,直接返回原字符串
+ if (source == null || source.isEmpty()) {
+ log.debug("源字符串为空,直接返回");
+ return source;
+ }
+
+ if (replacementMap == null || replacementMap.isEmpty()) {
+ log.debug("替换映射表为空,直接返回原字符串");
+ return source;
+ }
+
+ // 检查替换映射表中是否包含null键或值
+ for (Map.Entry entry : replacementMap.entrySet()) {
+ if (entry.getKey() == null) {
+ throw new IllegalArgumentException("替换映射表中不能包含null键");
+ }
+ if (entry.getValue() == null) {
+ log.warn("替换映射表中键 '{}' 的值为null,将作为空字符串处理", entry.getKey());
+ }
+ }
+
+ log.info("开始字符串替换处理,源字符串长度: {}, 替换规则数量: {}, 大小写敏感: {}, 整词匹配: {}, 使用正则: {}",
+ source.length(), replacementMap.size(), match(caseSensitive), match(wholeWord), match(useRegex));
+
+ String result = source;
+ int totalReplacements = 0;
+
+ // 遍历替换映射表,按顺序应用每个替换规则
+ for (Map.Entry entry : replacementMap.entrySet()) {
+ String patternStr = entry.getKey();
+ String replacement = entry.getValue() != null ? entry.getValue() : "";
+
+ try {
+ if (useRegex) {
+ // 使用正则表达式替换
+ log.info("应用替换规则(正则表达式替换): '{}' -> '{}'", patternStr, replacement);
+ result = applyRegexReplacement(result, patternStr, replacement, caseSensitive, wholeWord);
+ } else {
+ // 使用普通字符串替换
+ log.info("应用替换规则(普通字符串替换): '{}' -> '{}'", patternStr, replacement);
+ result = applyLiteralReplacement(result, patternStr, replacement, caseSensitive, wholeWord);
+ }
+
+ // 统计替换次数(通过比较字符串长度变化估算)
+ if (!result.equals(source)) {
+ totalReplacements++;
+ }
+
+ } catch (Exception e) {
+ log.error("替换规则处理失败 - 模式: '{}', 替换值: '{}', 错误: {}",
+ patternStr, replacement, e.getMessage());
+ // 发生错误时继续处理下一个规则,不中断整个流程
+ }
+ }
+
+ log.info("字符串替换完成,总应用规则数: {}, 实际产生变化的规则数: {}",
+ replacementMap.size(), totalReplacements);
+
+ return result;
}
/**
- * 偷梁换柱 - 支持正则表达式和多种替换选项
+ * 应用正则表达式替换
+ *
+ * @param source 源字符串
+ * @param regex 正则表达式模式
+ * @param replacement 替换内容
+ * @param caseSensitive 是否大小写敏感
+ * @param wholeWord 是否整词匹配
+ * @return 替换后的字符串
+ */
+ private static String applyRegexReplacement(String source, String regex, String replacement,
+ boolean caseSensitive, boolean wholeWord) {
+ String processedRegex = regex;
+
+ // 处理整词匹配:如果启用整词匹配且正则表达式尚未包含单词边界
+ if (wholeWord && !processedRegex.startsWith("\\b") && !processedRegex.contains("\\b")) {
+ processedRegex = "\\b" + processedRegex + "\\b";
+ log.info("添加单词边界,处理后的正则: {}", processedRegex); // trace
+ }
+
+ try {
+ // 设置正则表达式标志
+ int flags = caseSensitive ? 0 : Pattern.CASE_INSENSITIVE;
+ Pattern pattern = Pattern.compile(processedRegex, flags);
+ Matcher matcher = pattern.matcher(source);
+
+ String result = matcher.replaceAll(replacement);
+
+ // 记录替换详情(调试级别)
+ if (log.isTraceEnabled() && !result.equals(source)) {
+ int count = 0;
+ matcher.reset();
+ while (matcher.find()) count++;
+ log.info("正则替换完成: '{}' 匹配 {} 次", regex, count); // trace
+ }
+
+ return result;
+
+ } catch (Exception e) {
+ log.warn("正则表达式编译或执行失败,降级为普通字符串替换 - 模式: '{}', 错误: {}",
+ regex, e.getMessage());
+ // 降级处理:使用普通字符串替换
+ return applyLiteralReplacement(source, regex, replacement, caseSensitive, wholeWord);
+ }
+ }
+
+ /**
+ * 应用普通字符串替换
+ *
+ * @param source 源字符串
+ * @param literal 要查找的字符串
+ * @param replacement 替换内容
+ * @param caseSensitive 是否大小写敏感
+ * @param wholeWord 是否整词匹配
+ * @return 替换后的字符串
+ */
+ private static String applyLiteralReplacement(String source, String literal, String replacement,
+ boolean caseSensitive, boolean wholeWord) {
+ if (wholeWord) {
+ // 整词匹配处理:使用正则表达式实现单词边界匹配
+ try {
+ String regex = "\\b" + Pattern.quote(literal) + "\\b";
+ int flags = caseSensitive ? 0 : Pattern.CASE_INSENSITIVE;
+ Pattern pattern = Pattern.compile(regex, flags);
+ return pattern.matcher(source).replaceAll(replacement);
+ } catch (Exception e) {
+ log.warn("整词匹配处理失败,使用普通替换 - 模式: '{}'", literal);
+ // 降级为普通替换
+ }
+ }
+
+ // 普通字符串替换
+ if (caseSensitive) {
+ // 大小写敏感替换
+ return source.replace(literal, replacement);
+ } else {
+ // 大小写不敏感替换(需要手动实现)
+ return replaceIgnoreCase(source, literal, replacement);
+ }
+ }
+
+ /**
+ * 不区分大小写的字符串替换
+ *
+ * @param source 源字符串
+ * @param target 要查找的字符串
+ * @param replacement 替换内容
+ * @return 替换后的字符串
+ */
+ private static String replaceIgnoreCase(String source, String target, String replacement) {
+ if (source == null || target == null || replacement == null) {
+ return source;
+ }
+
+ StringBuilder result = new StringBuilder();
+ String lowerSource = source.toLowerCase();
+ String lowerTarget = target.toLowerCase();
+ int index = 0;
+ int targetLength = target.length();
+ int count = 0;
+
+ while (true) {
+ int pos = lowerSource.indexOf(lowerTarget, index);
+ if (pos == -1) break;
+
+ // 添加不匹配部分
+ result.append(source, index, pos);
+ // 添加替换内容
+ result.append(replacement);
+
+ index = pos + targetLength;
+ count++;
+ }
+
+ // 添加剩余部分
+ result.append(source.substring(index));
+
+ if (count > 0) {
+ log.info("不区分大小写替换完成: '{}' 匹配 {} 次", target, count); // trace
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * 偷梁换柱 - 使用默认参数(使用正则)
+ * @param source 源字符串
+ * @param replacementMap 替换映射关系
+ * @param caseSensitive 是否区分大小写
+ * @param wholeWord 是否整词匹配
+ * @return 替换后的字符串
+ */
+ public static String stealBeamsAndReplacePillars(String source, Map replacementMap,
+ boolean caseSensitive, boolean wholeWord) {
+ return stealBeamsAndReplacePillars(source, replacementMap, caseSensitive, wholeWord, true);
+ }
+
+ /**
+ * 偷梁换柱 - 使用默认参数(非整词匹配、使用正则)
* @param source 源字符串
* @param replacementMap 替换映射关系
* @param caseSensitive 是否区分大小写
@@ -1392,41 +1616,184 @@ public class FormatUtil {
}
/**
- * 偷梁换柱
+ * 偷梁换柱 - 使用默认参数(大小写不敏感、非整词匹配、使用正则)
+ *
* @param source 源字符串
* @param replacementMap 替换映射关系
- * @param caseSensitive 是否区分大小写
- * @param wholeWord 是否整词匹配
* @return 替换后的字符串
*/
- public static String stealBeamsAndReplacePillars(String source, Map replacementMap,
- boolean caseSensitive, boolean wholeWord) {
- if (source == null || replacementMap == null || replacementMap.isEmpty()) {
- return source;
- }
-
- String result = source;
-
- for (Map.Entry entry : replacementMap.entrySet()) {
- String regex = entry.getKey();
- String replacement = entry.getValue();
-
- // 处理整词匹配
- if (wholeWord && !regex.startsWith("\\b")) {
- regex = "\\b" + regex + "\\b";
- }
-
- try {
- int flags = caseSensitive ? 0 : Pattern.CASE_INSENSITIVE;
- Pattern pattern = Pattern.compile(regex, flags);
- Matcher matcher = pattern.matcher(result);
- result = matcher.replaceAll(replacement);
- } catch (Exception e) {
- System.err.println("正则表达式错误: " + regex + " - " + e.getMessage());
- }
- }
-
- return result;
+ public static String stealBeamsAndReplacePillars(String source, Map replacementMap) {
+ return stealBeamsAndReplacePillars(source, replacementMap, false, false, true);
}
+ // ========== JSON对象再次加工 ==========
+
+ /**
+ * 加载并预处理JSON文件
+ *
+ * 该方法读取JSON文件内容,解析为对象列表,并对所有键名进行标准化处理,
+ * 将键名转换为双花括号格式({{key}})。主要用于模板处理或数据转换场景。
+ *
+ * 处理流程:
+ *
+ * - 读取JSON文件内容为字符串
+ * - 使用FastJSON库解析为对象列表
+ * - 递归处理所有对象的键名,转换为{{key}}格式
+ *
+ *
+ * @param processJSONFile JSON文件路径,不能为null或空字符串
+ * @return 包含预处理后对象的列表,列表中的每个对象的所有键名都已转换为{{key}}格式
+ * @throws IOException 当文件读取失败、文件不存在或文件格式错误时抛出
+ * @throws IllegalArgumentException 当processJSONFile为null或空字符串时抛出
+ */
+ public static List