如何用正则移除JSON节点键中#及后续内容?现有代码异常
移除JSON键中#及后续内容的正确实现
需求说明
需要移除JSON对象中键的#及之后的所有内容,例如将键"DynamicAttribute#1279930005#ZZ8400"修改为"DynamicAttribute",同时保留原JSON的所有其他字段。
目标JSON示例
{ "uniqueCode": "ZZ", "entity": "PROFILE", "id": "e2b627b360d664377b227b--70378143#1", "data": [ "DynamicAttribute" ], "values": { "DynamicAttribute#1279930005#ZZ8400": [ { "property": "activeFlag", "currentState": true, "previousState": null } ] }, "DATE_TIME": "05-Apr-2023 19:17:14.376" }
错误尝试分析
你之前的代码存在两个核心问题:
- 丢失原JSON结构:仅提取了
values节点,没有保留原JSON的其他字段(比如uniqueCode、entity等)。 - 字符串替换逻辑错误:直接对
objectNode.toString()执行replaceAll("\\#.*", "\"["),会把#之后的所有字符串(包括正常的JSON结构)全部替换为"[,导致JSON被截断破坏。
错误代码:
String eventData; //Has the above json payload ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode = objectMapper.readTree(eventData); ObjectNode objectNode = objectMapper.convertValue(jsonNode.get("values"), ObjectNode.class); objectNode.toString().replaceAll("\\#.*", "\"[");
正确解决方案
通过遍历values节点的所有键,逐个修改键名并保留值,同时保留整个JSON的原始结构:
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import java.util.ArrayList; import java.util.List; public class JsonKeyModifier { public static void main(String[] args) throws Exception { String eventData = "{\"uniqueCode\":\"ZZ\",\"entity\":\"PROFILE\",\"id\":\"e2b627b360d664377b227b--70378143#1\",\"data\":[\"DynamicAttribute\"],\"values\":{\"DynamicAttribute#1279930005#ZZ8400\":[{\"property\":\"activeFlag\",\"currentState\":true,\"previousState\":null}]},\"DATE_TIME\":\"05-Apr-2023 19:17:14.376\"}"; ObjectMapper objectMapper = new ObjectMapper(); // 读取完整根节点,保留所有原始字段 JsonNode rootNode = objectMapper.readTree(eventData); if (rootNode.has("values") && rootNode.get("values").isObject()) { ObjectNode valuesNode = (ObjectNode) rootNode.get("values"); // 将键转为列表,避免遍历中修改节点结构引发异常 List<String> oldKeys = new ArrayList<>(valuesNode.fieldNames()); for (String oldKey : oldKeys) { // 截取#之前的部分作为新键名 String newKey = oldKey.split("#")[0]; // 获取旧键对应的值 JsonNode value = valuesNode.get(oldKey); // 设置新键值对 valuesNode.set(newKey, value); // 移除旧键 valuesNode.remove(oldKey); } } // 输出处理后的完整JSON String processedJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode); System.out.println(processedJson); } }
代码要点
- 读取完整的根
JsonNode,确保所有原始字段(uniqueCode、DATE_TIME等)都被保留。 - 遍历
values节点的键时,先转成ArrayList,避免在遍历过程中修改节点结构导致的并发修改异常。 - 使用
split("#")[0]精准截取#之前的键名,不会破坏其他JSON结构。 - 最后序列化整个根节点,得到完整的、符合要求的JSON字符串。
内容的提问来源于stack exchange,提问作者Scarlett John
相关产品推荐
相关产品推荐

