如何用Java正则表达式拆分字符串并忽略括号包裹的分组?
解决Java正则拆分嵌套结构键值对的问题
我来帮你搞定这个需求!你遇到的核心问题是普通的逗号拆分会破坏嵌套大括号里的结构,而Java正则其实可以通过**平衡匹配(递归引用)**来正确识别顶层的键值对,同时保留嵌套的大括号结构。下面是具体的解决方案:
思路分析
原字符串是方括号包裹的逗号分隔键值对,其中部分值是嵌套的{...}结构。我们需要:
- 先移除首尾的方括号
- 用支持嵌套结构的正则匹配每个完整的键值对,避免拆分大括号内的逗号
- 按需给纯字母的值添加引号(匹配你期望的
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
相关产品推荐
相关产品推荐

