如何修正正则表达式以正确处理短JSON值的掩码需求?
修复JSON短值掩码时的格式异常问题
问题场景
原代码用于对JSON中指定键的字符串值前5个字符进行掩码,当值长度≥5时工作正常:
String s = "{ \"Name1\":\"Cristhoper David\", \"pass\":\"123456789123\" }"; System.out.println(s .replaceAll("(?<=Name1\\":\\")(.{1,5})(.*?)", "*****$2") .replaceAll("(?<=pass\\":\\")(.{1,5})(.*?)", "*****$2") );
输出:
{ "Name1":"*****hoper David", "pass":"*****6789123" }
但当Name1的值长度小于5时,JSON格式会出现异常,引号或逗号丢失:
例如输入:
String s = "{ \"Name1\":\"Joe\", \"pass\":\"123456789123\" }";
错误输出:
{ "Name1":"***** "pass":"*****6789123" }
输入:
String s = "{ \"Name1\":\"Jo\", \"pass\":\"123456789123\" }";
错误输出:
{ "Name1":"*****"pass":"*****6789123" }
期望输出(短值时):
{ "Name1":"*****","pass":"*****6789123" }
问题原因
原正则表达式中的.*?是惰性匹配,但未限制匹配范围。当值长度小于5时,(.{1,5})会匹配到值的结尾,后续的.*?会继续匹配后面的引号、空格甚至逗号,导致这些字符被包含在替换分组中,最终丢失并破坏JSON格式。
解决方案
修改正则,将匹配范围限制在当前键的字符串值内部(即闭合引号"之前),避免匹配到引号外的内容。
修正后的代码:
String s = "{ \"Name1\":\"Joe\", \"pass\":\"123456789123\" }"; System.out.println(s .replaceAll("(?<=Name1\\":\\")([^"]{0,5})([^"]*)", "*****$2") .replaceAll("(?<=pass\\":\\")([^"]{0,5})([^"]*)", "*****$2") );
正则说明
[^"]:匹配非引号的任意字符,确保不会超出当前字符串值的范围([^"]{0,5}):匹配值的前0到5个字符(兼容长度小于5的情况)([^"]*):匹配值中剩余的所有非引号字符
验证结果
- 当
Name1值为"Joe"时,输出:
{ "Name1":"*****","pass":"*****6789123" }
- 当
Name1值为"Jo"时,输出:
{ "Name1":"*****","pass":"*****6789123" }
- 当
Name1值长度≥5时,依然保持正常掩码效果:
{ "Name1":"*****hoper David", "pass":"*****6789123" }
内容的提问来源于stack exchange,提问作者JAK
相关产品推荐
相关产品推荐

