Java如何编写正则拆分含嵌套对象的JSON串,逐个提取根级对象
正确实现方案
不要用正则拆分JSON,结构化数据用流解析才是稳定可维护的解法,你对Jackson的功能认知有误,Jackson完全支持流式逐元素读取数组,不需要一次性加载整个数组到内存。
方案1:Jackson流式解析(生产环境首选)
用Jackson的JsonParser流式读取,自动处理嵌套结构,单条数据解析异常可单独处理,不影响整体流程:
import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.FileInputStream; import java.io.IOException; // 先定义对应业务实体类 class RepairRecord { private String vinForRepair; private String dateOfRepair; private Integer mileage; private List<RepairItem> items; // 省略getter、setter } class RepairItem { private String description; private Integer quantity; private Double price; private String metric; // 省略getter、setter } public class JsonStreamReader { public static void main(String[] args) { ObjectMapper objectMapper = new ObjectMapper(); JsonFactory jsonFactory = objectMapper.getFactory(); // 支持直接传文件流/网络流,不需要把整个JSON读成字符串 try (JsonParser parser = jsonFactory.createParser(new FileInputStream("你的JSON文件路径"))) { // 如果你的JSON是包裹在数组[]里的,先跳过数组开头标记,没有包裹可以跳过这一步 if (parser.nextToken() != JsonToken.START_ARRAY) { throw new IllegalArgumentException("JSON根节点不是数组"); } // 逐个读取数组内的元素 while (parser.nextToken() != JsonToken.END_ARRAY) { try { RepairRecord record = parser.readValueAs(RepairRecord.class); // 正常处理单条业务数据 System.out.println("处理成功,VIN:" + record.getVinForRepair()); } catch (Exception e) { // 单条数据解析异常单独处理,不会中断整个读取流程 System.err.println("单条记录解析失败,已跳过:" + e.getMessage()); } } } catch (IOException e) { e.printStackTrace(); } } }
该方案优势:
- 内存占用极低,支持GB级大JSON文件处理
- 自动处理嵌套结构、格式兼容,不需要手动处理括号匹配
- 异常隔离性强,业务容错性高
方案2:正则拆分(仅适用于格式完全固定的临时场景)
你之前的split没生效是因为正则没有兼容空白字符差异,如果你能保证JSON格式100%固定、根对象首个属性固定是vinForRepair,可以用修正后的正则:
// 兼容换行和空白字符差异 String[] jsonObjectStringArray = jsonString.split("\\},\\s*\\n\\s*\"vinForRepair\""); // 补全拆分后丢失的括号和属性前缀 if (jsonObjectStringArray.length > 0) { jsonObjectStringArray[0] = jsonObjectStringArray[0] + "}"; for (int i = 1; i < jsonObjectStringArray.length; i++) { jsonObjectStringArray[i] = "{\"vinForRepair\"" + jsonObjectStringArray[i]; } }
注意:该方案容错性极差,只要属性顺序、缩进、换行格式变化就会失效,不推荐生产环境使用。
内容的提问来源于stack exchange,提问作者Ivan Ivanov
相关产品推荐
相关产品推荐

