如何用正则解析Java项目导入功能中含多层大括号中括号的字符串
解决方案
你可以通过以下两种稳定方案实现外层对象与内层对象的关联解析,优先推荐括号计数法,不会出现内容丢失的问题:
方案1:括号计数分层拆分(推荐)
你的类JSON结构括号严格成对,通过计数器分层拆分的容错性远高于纯正则匹配,不会丢失内容。
Java实现步骤:
- 第一步:先清理原始字符串所有空白符(换行、空格、制表符)避免干扰计数,用
str.replaceAll("\\s+", "")即可 - 第二步:遍历清理后的字符串,用大括号计数器拆分出所有完整的外层对象:
- 跳过最外层开头的
[后开始遍历 - 遇到
{计数器+1,遇到}计数器-1 - 当计数器归0时,说明刚好读取完一个完整外层对象,截取这段字符串即可
- 跳过最外层开头的
- 第三步:对每个拆分出的外层对象,用你已经写好的内层正则匹配,得到的就是该外层对象对应的所有内层元素,自然完成关联。
参考代码片段:
// 1. 清理原始字符串空白 String rawStr = "[\n {\n [\n {[oid1,oid2],VAL,id1},{[oid2],VAL,id2},\n {[oid2,oid3,oid4],VAL,id3}\n ]\n },\n {\n [\n {[oid5,oid6],VAL,id1},\n {[oid7,oid8],VAL,id3}\n ]\n }\n]"; String cleanStr = rawStr.replaceAll("\\s+", ""); // 2. 拆分所有外层对象 List<String> outerObjList = new ArrayList<>(); int curlyCount = 0; int startIndex = 0; // 跳过最外层的首尾方括号 for (int i = 1; i < cleanStr.length() - 1; i++) { char c = cleanStr.charAt(i); if (c == '{') { if (curlyCount == 0) startIndex = i; curlyCount++; } else if (c == '}') { curlyCount--; if (curlyCount == 0) { outerObjList.add(cleanStr.substring(startIndex, i + 1)); } } } // 3. 逐个解析外层对象关联内层元素 Pattern innerPattern = Pattern.compile("\\{\\[([^}\\]]+)\\],([A-Z_]+),([^}]+)}"); for (String outerObj : outerObjList) { Matcher matcher = innerPattern.matcher(outerObj); List<InnerElement> innerList = new ArrayList<>(); while (matcher.find()) { // 提取三个分组封装为你的内层对象 InnerElement inner = new InnerElement(); inner.setOidList(Arrays.asList(matcher.group(1).split(","))); inner.setType(matcher.group(2)); inner.setId(matcher.group(3)); innerList.add(inner); } // innerList即为当前外层对象对应的所有内层元素,直接绑定关联即可 }
方案2:嵌套正则匹配(仅适合固定嵌套层数场景)
如果你的结构固定为每个外层对象仅包裹一层内层列表,没有更深的嵌套,也可以直接用正则捕获外层分组:
使用正则\\{\\[((?:\\{\\[[^}\\]]+\\],[A-Z_]+,[^}]+},?)+)\\]}可以直接匹配每个外层对象,分组1就是当前外层内所有内层对象的拼接字符串,再用你原来的内层正则拆分分组1即可。
注意:该方案仅适用于嵌套层数固定的场景,如果嵌套层数可变正则会失效,优先使用方案1。
内容的提问来源于stack exchange,提问作者Chris van Darg
相关产品推荐
相关产品推荐

