如何用Java Regex提取JS回调中的嵌套JSON内容
从回调包裹的字符串中提取嵌套JSON的Java实现
这问题我之前做前后端对接时也碰到过——直接用\{.*\}这种简单正则肯定踩坑,因为JSON里的嵌套大括号会让正则要么提前截断,要么过度匹配。给你两种靠谱的解决方案,适配不同Java版本:
方法一:Java 9+ 递归正则(简洁版)
Java 9及以后的正则引擎支持递归引用捕获组,刚好可以完美处理嵌套的大括号结构:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class JsonExtractor { public static void main(String[] args) { String wrappedJson = "_mycallback({ \"timestamp\":654321, \"items\":[ { \"id\":111, \"title\":\"Test Item 111\" }, { \"id\":222, \"title\":\"Test Item 222\" } ] });"; // 核心正则:匹配_mycallback(...)内的完整嵌套JSON Pattern pattern = Pattern.compile( "_mycallback\\(\\s*(\\{(?:[^{}]|(?1))*\\})\\s*\\);", Pattern.DOTALL ); Matcher matcher = pattern.matcher(wrappedJson); if (matcher.find()) { String pureJson = matcher.group(1); System.out.println(pureJson); // 这里可以直接把pureJson传给Jackson/Gson解析 } else { System.out.println("未找到有效JSON结构"); } } }
正则逻辑拆解:
_mycallback\\(:精准匹配前缀和左括号\\s*:忽略括号前后的任意空白(包括换行)(\\{(?:[^{}]|(?1))*\\}):递归匹配核心:\\{匹配最外层左大括号(?:[^{}]|(?1)):匹配非括号字符,或者递归引用第一个捕获组(也就是匹配内部的嵌套大括号)*\\}:直到匹配到最外层的右大括号
Pattern.DOTALL:让.能匹配换行符,兼容多行JSON的情况
方法二:Java 8及以下兼容方案(手动计数法)
如果你的项目还在使用Java 8或更早版本,递归正则用不了,那就用手动计数大括号的方式,逻辑简单且更稳妥:
public class JsonExtractor { public static void main(String[] args) { String wrappedJson = "_mycallback({ \"timestamp\":654321, \"items\":[ { \"id\":111, \"title\":\"Test Item 111\" }, { \"id\":222, \"title\":\"Test Item 222\" } ] });"; // 找到第一个左大括号的位置 int startIdx = wrappedJson.indexOf('{'); if (startIdx == -1) { System.out.println("未找到JSON起始标记"); return; } int bracketCount = 1; int endIdx = startIdx + 1; // 遍历字符,计数大括号平衡 while (endIdx < wrappedJson.length() && bracketCount > 0) { char currentChar = wrappedJson.charAt(endIdx); if (currentChar == '{') { bracketCount++; } else if (currentChar == '}') { bracketCount--; } endIdx++; } // 确认大括号平衡后截取JSON if (bracketCount == 0) { String pureJson = wrappedJson.substring(startIdx, endIdx - 1); System.out.println(pureJson); } else { System.out.println("JSON结构存在未闭合的大括号"); } } }
逻辑说明:
- 先定位到第一个
{,作为JSON的起始点 - 从起始点后开始遍历,遇到
{就加计数,遇到}就减计数 - 当计数回到0时,说明找到了最外层的
},此时截取的字符串就是完整的JSON - 如果遍历到末尾计数还不为0,说明JSON结构有语法错误
额外注意点
- 如果输入字符串中有多个
_mycallback调用,可以循环调用matcher.find()(正则法)或者调整起始位置(手动计数法)来逐个提取 - 不管用哪种方法,提取后建议用Jackson、Gson等JSON库解析验证,确保结构正确
内容的提问来源于stack exchange,提问作者anuni
相关产品推荐
相关产品推荐

