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

如何用Java正则表达式拆分字符串并忽略括号包裹的分组?

解决Java正则拆分嵌套结构键值对的问题

我来帮你搞定这个需求!你遇到的核心问题是普通的逗号拆分会破坏嵌套大括号里的结构,而Java正则其实可以通过**平衡匹配(递归引用)**来正确识别顶层的键值对,同时保留嵌套的大括号结构。下面是具体的解决方案:

思路分析

原字符串是方括号包裹的逗号分隔键值对,其中部分值是嵌套的{...}结构。我们需要:

  1. 先移除首尾的方括号
  2. 用支持嵌套结构的正则匹配每个完整的键值对,避免拆分大括号内的逗号
  3. 按需给纯字母的值添加引号(匹配你期望的apple="peer"格式)

完整代码实现

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class KeyValueParser {
    public static void main(String[] args) {
        // 你的原始输入字符串
        String input = "[potato=carrot,test=12b,apple=peer,tree={oak=1,birch={value=3}},foo=bar]";
        
        // 第一步:去掉首尾的方括号
        String content = input.replaceAll("^\\[|\\]$", "");
        
        // 第二步:定义支持嵌套大括号的正则表达式
        // 解释:
        // (\w+) 匹配键名(字母/数字/下划线)
        // = 匹配等号
        // ( ... ) 匹配值:要么是嵌套的大括号结构,要么是非逗号的普通值
        // \{(?:[^{}]++|(?2))*\} 递归匹配嵌套大括号,(?2)引用第二个捕获组实现递归
        Pattern pattern = Pattern.compile("(\\w+)=(\\{(?:[^{}]++|(?2))*\\}|[^,]+)");
        Matcher matcher = pattern.matcher(content);
        
        List<String> keyValueList = new ArrayList<>();
        while (matcher.find()) {
            String key = matcher.group(1);
            String value = matcher.group(2);
            
            // 第三步:给纯字母的非大括号值添加引号(匹配你要的apple="peer"格式)
            if (!value.startsWith("{") && value.matches("[a-zA-Z]+")) {
                value = "\"" + value + "\"";
            }
            
            keyValueList.add(key + "=" + value);
        }
        
        // 转换为你需要的字符串数组
        String[] resultArray = keyValueList.toArray(new String[0]);
        
        // 输出验证结果
        System.out.println("拆分后的数组元素:");
        for (String pair : resultArray) {
            System.out.println(pair);
        }
        System.out.println("\n按空格连接的结果:");
        System.out.println(String.join(" ", resultArray));
    }
}

运行结果

执行代码后,按空格连接的结果完全符合你的期望:

potato="carrot" test=12b apple="peer" tree={oak=1,birch={value=3}} foo="bar"

为什么之前的正则没生效?

普通的split(",")会把嵌套大括号里的逗号也当成分隔符,导致tree={oak=1这种错误结果。而我们用的正则通过递归引用(?2),可以准确识别嵌套的大括号结构,只拆分顶层的逗号,完美保留内部的嵌套内容。

灵活调整

如果你的键名包含非字母/数字的字符,可以把键名的匹配规则从(\w+)改成([^=]+);如果不需要给纯字母值加引号,直接移除添加引号的判断逻辑即可。

内容的提问来源于stack exchange,提问作者Oromis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:34:38