
本文介绍如何通过条件判断结合双正则匹配,实现对形如 `key(value)` 和 `key(nestedkey(val)otherkey(val))` 的混合格式进行正确解析,确保简单值(如 `value(123)`)也能作为内层键存入 map,其值为空字符串。
在实际文本解析场景中,常遇到结构看似统一但语义分层的输入:外层是固定格式的键(大写字母+括号),而括号内内容可能为纯值(如 123),也可能是多个嵌套键值对(如 INNERVALUE(123)OTHERVALUE(456))。Java 原生正则不支持“分支重置组”((?|...))的完整语义(该特性在 PCRE/Perl 中可用,但 java.util.regex 不支持),因此不能依赖单个正则通过重置捕获组编号来统一处理两类情况。
正确的解法是分层识别 + 语义判定:
- 先用外层正则 ([A-Z]+)\((.*)\) 提取 KEY 和括号内全部内容;
- 再对括号内容做「是否含嵌套键值」的判定——关键在于:若内容中不存在形如 XXX(...) 的子结构,就将其整体视为一个无值键(value-as-key),映射为 {value → ""};否则启用内层正则逐个提取。
以下是优化后的完整实现(已适配 Java 11+ 的 String.lines()):
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexNestedParser {
public static void main(String[] args) {
// 外层匹配:提取 KEY 和括号内原始内容(贪婪匹配)
Pattern outerPattern = Pattern.compile("([A-Z]+)\\((.*)\\)");
// 内层匹配:精准提取嵌套 KEY(VALUE),避免跨括号误匹配([^()]* 确保不跨越括号)
Pattern innerPattern = Pattern.compile("([A-Z]+)\\(([^()]*)\\)");
String input = """
VALUE(123)
OUTERVALUE(INNERVALUE(123)OTHERVALUE(456))
""";
Map> result = new HashMap<>();
input.lines()
.filter(line -> !line.trim().isEmpty()) // 跳过空行
.forEach(line -> {
Matcher outerMatcher = outerPattern.matcher(line);
if (!outerMatcher.find()) return; // 跳过不匹配行
String key = outerMatcher.group(1);
String rawValue = outerMatcher.group(2);
Map innerMap = new HashMap<>();
// 判定 rawValue 是否包含任何嵌套键值结构
if (innerPattern.asPredicate().test(rawValue)) {
// 存在嵌套 → 按 innerPattern 提取所有 KEY(VALUE)
Matcher innerMatcher = innerPattern.matcher(rawValue);
while (innerMatcher.find()) {
innerMap.put(innerMatcher.group(1), innerMatcher.group(2));
}
} else {
// 无嵌套 → 整个 rawValue 作为键,值为空字符串
innerMap.put(rawValue, "");
}
result.put(key, innerMap);
});
System.out.println(result);
// 输出:{VALUE={123=}, OUTERVALUE={INNERVALUE=123, OTHERVALUE=456}}
}
} 关键细节说明:
- ✅ innerPattern 使用 ([^()]*) 替代 (.*),防止在 INNERVALUE(123)OTHERVALUE(456) 中因贪婪匹配导致 group(2) 捕获到 123)OTHERVALUE(456 —— 这是原代码未正确解析的根本原因;
- ✅ 使用 innerPattern.asPredicate().test(rawValue) 进行轻量级预检,比启动 Matcher 更高效,且逻辑清晰;
- ✅ 显式 filter(...isEmpty()) 避免空行干扰,增强鲁棒性;
- ❌ 不要尝试用 (?|...) 或 (?R) 等高级语法——Java 正则引擎不支持,强行使用会抛 PatternSyntaxException。
此方案不依赖外部库,完全基于 JDK 内置 API,结构清晰、可读性强,适用于配置解析、DSL 简化语法等典型场景。










