
本文讲解如何使用正则表达式安全地掩码 JSON 字符串中指定字段(如 "Name1"、"pass")的前 5 个字符,避免因原始值长度不足导致引号、逗号等结构符号被意外截断或丢失。
本文讲解如何使用正则表达式安全地掩码 json 字符串中指定字段(如 `"name1"`、`"pass"`)的前 5 个字符,避免因原始值长度不足导致引号、逗号等结构符号被意外截断或丢失。
在处理 JSON 字符串的敏感字段(如姓名、密码)时,常需对值的前几位进行掩码(例如用 ***** 替代)。初学者易采用类似 (?<=Name1":")(.{1,5})(.*?) 的正向先行断言 + 捕获组方式,但该写法存在严重缺陷:当目标值长度 < 5(如 "Joe")时,(.{1,5}) 会贪婪匹配至后续引号或逗号前,导致 $2 捕获内容包含非法边界(如 ", "pass":"),最终替换后破坏 JSON 结构。
根本问题在于:*原正则未限定匹配范围的终止边界,使 `.?过度回溯并吞掉关键分隔符("、,、}`)**。
✅ 正确思路是:仅匹配“字段名后引号内、且位于前 5 位之内的单个字符”,不捕获、不依赖后续内容,从而彻底规避结构破坏。
推荐使用以下精准正则(适用于标准双引号 JSON):
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
String s = "{ \"Name1\":\"Joe\", \"pass\":\"123456789123\" }";
String masked = s.replaceAll(
"(?<=\"(?:Name1|pass)\":\")[^\"]{0,4}[^\"]",
"*****"
).replaceAll(
"(?<=\"(?:Name1|pass)\":\")[^\"]{0,4}[^\"]",
"*****"
);
// 注意:此处两次 replaceAll 是为兼容 Java 8 及以下(不支持重复替换同一位置)
// 实际建议用循环或更健壮方案(见下文)但更简洁、安全且一次生效的写法是:
String s = "{ \"Name1\":\"Joe\", \"pass\":\"123456789123\" }";
// ✅ 推荐:单次正则,精确控制匹配位置
String result = s.replaceAll(
"(?<=\"(?:Name1|pass)\":\")[^\"]{0,4}[^\"]",
"*****"
);
System.out.println(result);
// 输出:{ "Name1":"*****", "pass":"*****6789123" }? 正则解析:
- (?<=\"(?:Name1|pass)\":\"):正向先行断言,确保匹配位置紧接在 "Name1":" 或 "pass":" 之后;
- [^\"]{0,4}:匹配 0–4 个非引号字符(即前 4 个可掩码字符);
- [^\"]:再匹配第 5 个(或最后一个)非引号字符——这保证了:
- 若值长 ≥ 5:匹配前 5 个字符;
- 若值长 = 3(如 "Joe"):[^\"]{0,4} 匹配前 2 个(Jo),[^\"] 匹配第 3 个(e),共 3 字符 → 全部被 ***** 替换,长度统一为 5;
- 关键:[^\"] 绝不会匹配到结束引号 ",因此 "、,、} 等结构符号始终保留。
⚠️ 注意事项:
- 不要使用 .*? 或 (.{1,5})(.*?) 类模糊捕获,这是结构破坏的根源;
- 若需同时处理多个字段,用 (?:Name1|pass|token|id) 扩展非捕获组;
- 对嵌套 JSON 或含转义引号(\")的场景,正则将失效——此时应改用 JSON 解析器(如 Jackson/Gson)进行结构化脱敏;
- Java 中 replaceAll() 是全局替换,上述正则天然支持多字段同批处理;
- 如需严格保证每个字段恰好掩码 5 位(短值补星号),可在替换后二次处理:result.replace("\"*****\"", "\"*****\"")(不推荐,逻辑冗余);实际业务中 ***** 作为固定掩码符已满足合规要求。
✅ 最佳实践总结:
用 (?<=...)[^\"]{0,4}[^\"] 替代 (?<=...)(.{1,5})(.*?) —— 以「边界感知」代替「贪婪捕获」,从正则设计层面根治 JSON 结构损坏问题。

















