Java中Regex的replaceAll方法不符合预期,替换URL时出错
解决Java中替换JSON内URL时破坏结构的问题
我之前也踩过直接用正则处理JSON字符串的坑!你遇到的Expected ',' instead of '''错误,本质是直接用replaceAll操作JSON字符串时,正则不小心匹配到了JSON语法的关键部分(比如引号、逗号附近的内容),或者替换后的字符串干扰了原有的JSON结构。下面给你两种靠谱的解决思路:
方法一:优先用JSON解析库处理(最安全)
直接操作JSON字符串很容易出问题,正确的姿势应该是先把JSON解析成结构化的节点,再遍历所有字符串值做替换,最后重新生成JSON字符串。这样完全不会破坏JSON的语法结构。
以常用的Jackson库为例:
步骤1:导入依赖(Maven为例)
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> <!-- 用最新稳定版即可 --> </dependency>
步骤2:编写替换代码
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.TextNode; import java.util.Iterator; public class JsonUrlReplacer { public static void main(String[] args) throws Exception { String originalJson = "你的大JSON字符串"; ObjectMapper mapper = new ObjectMapper(); // 解析JSON为节点树 JsonNode rootNode = mapper.readTree(originalJson); // 递归替换所有字符串中的目标URL JsonNode modifiedNode = replaceTargetUrls(rootNode); // 重新生成合法的JSON字符串 String updatedJson = mapper.writeValueAsString(modifiedNode); System.out.println(updatedJson); } private static JsonNode replaceTargetUrls(JsonNode node) { // 处理字符串节点:替换URL if (node.isTextual()) { String textValue = node.asText(); // 精准匹配目标URL格式,只替换域名部分 String replacedText = textValue.replaceAll("https://[^/]+/api/FHIR/DSTU2/", "https://api.anotherdomain.edu/FHIR/DSTU2/"); return new TextNode(replacedText); } // 处理对象节点:遍历所有字段 else if (node.isObject()) { ObjectNode objectNode = ((ObjectNode) node).deepCopy(); Iterator<String> fieldNames = objectNode.fieldNames(); while (fieldNames.hasNext()) { String fieldName = fieldNames.next(); objectNode.set(fieldName, replaceTargetUrls(objectNode.get(fieldName))); } return objectNode; } // 处理数组节点:遍历所有元素 else if (node.isArray()) { ArrayNode arrayNode = ((ArrayNode) node).deepCopy(); for (int i = 0; i < arrayNode.size(); i++) { arrayNode.set(i, replaceTargetUrls(arrayNode.get(i))); } return arrayNode; } // 其他类型节点(数字、布尔等)直接返回 return node; } }
这个方法的核心是:只针对JSON中的字符串类型内容做替换,完全不会碰JSON的语法符号(引号、逗号、大括号等),从根源上避免结构破坏的问题。
方法二:优化正则表达式(仅限简单场景)
如果因为某些原因必须直接操作字符串,那就要把正则写得足够精准,确保只匹配双引号包裹的目标URL,不会误伤到JSON语法结构。
优化后的正则和替换代码:
String updatedJson = originalJson.replaceAll( "\"https://[^/\"]+/api/FHIR/DSTU2/\"", "\"https://api.anotherdomain.edu/FHIR/DSTU2/\"" );
正则说明:
":匹配字符串的双引号边界,确保我们只处理JSON里的字符串内容https://[^/\"]+:匹配域名部分,[^/\"]+表示匹配除了/和"之外的所有字符,避免匹配到URL之外的内容/api/FHIR/DSTU2/:固定的URL后缀
⚠️ 注意:这种方法还是有局限性,如果你的URL里包含转义的双引号(比如\"),正则就会失效,所以优先推荐方法一。
内容的提问来源于stack exchange,提问作者user2165673
相关产品推荐
相关产品推荐

