You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:31:16