使用正则表达式替换字符串模板出错,请求排查问题原因
正则匹配JSON片段失败的问题排查
问题场景
需要移除JSON字符串中类似以下的resSec相关片段:
"resSec":{"entry":{"key":"mem","value":"7397920259"},"entry":{"key":"core","value":"1806132"}},"preemRes"
涉及两种JSON结构:
- 包含多个
entry的resSec:
..."resSec":{"entry":{"key":"mem","value":"7397920259"},"entry":{"key":"core","value":"1806132"}},"preemRes"...
- 只包含单个
entry的resSec:
..."resSec":{"entry":{"key":"mem","value":"7397920259"}},"preemRes"..
使用以下Java代码处理后结果不符合预期:
String content2 = content.replaceAll("\"resSec(.*)\\}\\},\"preemRes", "\"preemRes"); System.out.println(content2);
正则表达式的错误点
贪婪匹配导致范围失控
正则中的(.*)是贪婪模式,会尽可能匹配最长的字符序列。如果字符串里存在多处}},或者后续还有其他类似结构,它会直接匹配到最后一个}},\"preemRes的位置,把中间不该删除的内容也一并删掉,完全偏离预期。匹配逻辑无法精准定位
虽然\\}\\}的转义是正确的(Java字符串中需要用\\}表示单个}),但贪婪模式的.*会跳过resSec内部的}},直接往后找最远的匹配终点,根本无法精准定位到当前resSec的闭合位置。
修正方案
把贪婪匹配改成非贪婪匹配,将(.*)替换为(.*?),这样正则会尽可能匹配最短的字符序列,找到第一个}},\"preemRes就停止匹配。修正后的代码:
String content2 = content.replaceAll("\"resSec(.*?)\\}\\},\"preemRes", "\"preemRes");
额外提示
如果你的JSON结构存在更复杂的嵌套(比如entry内部还有多层{}),正则表达式依然可能出现匹配错误。这种情况下更推荐使用专业的JSON解析库(比如Jackson、Gson)来定位并删除resSec节点,这比正则更可靠。
内容的提问来源于stack exchange,提问作者Alatau
相关产品推荐
相关产品推荐

