
本文介绍如何在 java 中使用正则表达式动态区分两种结构:当括号内为纯值(如 `value(123)`)时,将其整体作为 inner map 的键、值设为空字符串;当为嵌套键值对(如 `outervalue(innervalue(123)othervalue(456))`)时,则正常提取子键值对。核心在于先匹配外层结构,再通过预检判断是否需降级为单键解析。
要实现题目所需的语义解析——即对 VALUE(123) 解析为 {123=""},而对 OUTERVALUE(INNERVALUE(123)OTHERVALUE(456)) 解析为 {INNERVALUE="123", OTHERVALUE="456"}——关键不在于“重置捕获组编号”,而在于逻辑分支控制:先识别外层键,再根据其值内容的结构决定 inner map 的构建策略。
✅ 核心思路
- 外层匹配:用 ([A-Z]+)\((.*)\) 提取 KEY(...) 中的 KEY 和括号内全部内容;
- 结构判别:检查括号内内容是否不含嵌套键值结构(即无形如 XXX(YYY) 的子模式),可借助 Pattern.asPredicate() 高效预检;
-
双路径解析:
- 若无嵌套 → 将整个 value 字符串作为 inner map 的唯一键,值设为 "";
- 若有嵌套 → 用更严谨的 ([A-Z]+)\(([^()]*)\)(禁止跨层括号)逐个提取子键值对。
? 为什么改用 ([^()]*)?原 .*? 在贪婪上下文中易跨括号匹配(如 INNERVALUE(123)OTHERVALUE(456) 中可能错误匹配到 INNERVALUE(123)OTHERVALUE),而 [^()]* 明确限定内部不能含括号,确保每个 XXX(YYY) 独立、无嵌套干扰。
✅ 完整可运行代码
import java.util.HashMap;
import java.util.Map;
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]+)\\((.*)\\)");
// 内层模式:安全匹配 XXX(YYY),要求 YYY 不含括号(防跨组)
Pattern innerPattern = Pattern.compile("([A-Z]+)\\(([^()]*)\\)");
String input = """
VALUE(123)
OUTERVALUE(INNERVALUE(123)OTHERVALUE(456))
SIMPLE(abc)
COMPLEX(A(1)B(2)C(3))
""";
Map> outer = new HashMap<>();
for (String line : input.split("\n")) {
line = line.trim();
if (line.isEmpty()) continue;
Matcher outerMatcher = outerPattern.matcher(line);
if (!outerMatcher.find()) continue; // 跳过非法行
String key = outerMatcher.group(1);
String value = outerMatcher.group(2);
Map innerMap = new HashMap<>();
// 判定 value 是否含嵌套键值结构
if (!innerPattern.asPredicate().test(value)) {
// 无嵌套 → 整个 value 作键,值为空字符串
innerMap.put(value, "");
} else {
// 有嵌套 → 逐个提取子键值对
Matcher innerMatcher = innerPattern.matcher(value);
while (innerMatcher.find()) {
innerMap.put(innerMatcher.group(1), innerMatcher.group(2));
}
}
outer.put(key, innerMap);
}
System.out.println(outer);
// 输出:{VALUE={123=}, OUTERVALUE={INNERVALUE=123, OTHERVALUE=456}, SIMPLE={abc=}, COMPLEX={A=1, B=2, C=3}}
}
} ⚠️ 注意事项
- 输入格式强依赖:本方案假设每行仅一个外层键值对,且括号严格配对、无转义或注释干扰;
- 性能友好:asPredicate().test() 是轻量预检,避免无效 matcher 创建;
- 扩展性提示:若未来需支持多层嵌套(如 A(B(C(1)))),应改用递归下降解析器或栈式分析,正则不再适用;
- 空值处理:示例中统一用空字符串 "" 表示无显式值,如需 null,请将 innerMap.put(value, "") 改为 innerMap.put(value, null)。
该方案以清晰的控制流替代复杂正则技巧,兼顾可读性、健壮性与可维护性,是处理此类半结构化文本的推荐实践。










