如何捕获带嵌套括号的正则模式?Java实现多级嵌套函数分词
处理Java中嵌套函数的分词问题
普通正则表达式确实搞不定嵌套括号的场景——你用的\(([^\)]+)\)会在遇到第一个右括号就停止匹配,根本识别不了嵌套层级。要解决这个问题,我们可以用**栈(Stack)**来跟踪括号深度,手动遍历字符串定位完整的函数调用,甚至递归处理内部的嵌套结构。
核心思路
- 遍历字符串,识别函数调用的起始位置(比如以
Function.开头的标识符,或者更通用的,找到左括号(前的合法函数名)。 - 用栈记录括号层级:遇到
(就入栈,遇到)就出栈,当栈深度回到0时,说明找到了一个完整的函数调用结束位置。 - 对于函数内部的参数内容,可以继续递归处理,提取嵌套的内层函数或其他内容。
Java代码实现
下面是一个示例实现,既能提取你期望的外层函数和括号内内容,还能递归挖出所有嵌套的内层函数:
import java.util.ArrayList; import java.util.List; import java.util.Stack; public class FunctionTokenizer { public static List<String> tokenizeNestedFunctions(String input) { List<String> results = new ArrayList<>(); int length = input.length(); Stack<Integer> bracketStack = new Stack<>(); // 先提取完整的外层函数 int functionStart = 0; for (int i = 0; i < length; i++) { char c = input.charAt(i); if (c == '(') { bracketStack.push(i); // 记录第一个左括号前的函数起始位置 if (bracketStack.size() == 1) { functionStart = 0; } } else if (c == ')') { if (!bracketStack.isEmpty()) { bracketStack.pop(); // 栈空时,说明拿到了完整的外层函数 if (bracketStack.isEmpty()) { String fullFunction = input.substring(functionStart, i + 1); results.add(fullFunction); // 提取括号内的内容(对应你要的第二个结果) String innerContent = input.substring(fullFunction.indexOf('(') + 1, i); results.add(innerContent); // 递归提取内部的嵌套函数(可选,按需开启) extractInnerFunctions(innerContent, results); break; } } } } return results; } // 递归提取内部的嵌套函数 private static void extractInnerFunctions(String innerContent, List<String> results) { int length = innerContent.length(); Stack<Integer> bracketStack = new Stack<>(); int funcStart = -1; for (int i = 0; i < length; i++) { char c = innerContent.charAt(i); if (c == '(') { bracketStack.push(i); if (bracketStack.size() == 1) { // 向前找函数名的起始(支持带点的函数名,比如Function.toDecimal) int j = i - 1; while (j >= 0 && (Character.isLetterOrDigit(innerContent.charAt(j)) || innerContent.charAt(j) == '.')) { j--; } funcStart = j + 1; } } else if (c == ')') { if (!bracketStack.isEmpty()) { bracketStack.pop(); if (bracketStack.isEmpty() && funcStart != -1) { String innerFunc = innerContent.substring(funcStart, i + 1); // 避免重复添加 if (!results.contains(innerFunc)) { results.add(innerFunc); } // 继续递归处理这个内层函数的参数 String innerFuncContent = innerContent.substring(funcStart + innerFunc.indexOf('(') + 1, i); extractInnerFunctions(innerFuncContent, results); funcStart = -1; } } } } } public static void main(String[] args) { String input = "Function.greaterThan(Function.toDecimal(input.a.b),7.2)"; List<String> tokens = tokenizeNestedFunctions(input); System.out.println("分词结果:"); for (String token : tokens) { System.out.println(token); } } }
代码说明
- 外层函数提取:遍历输入字符串,用栈跟踪括号深度,栈空时截取完整的外层函数,同时提取括号内的全部内容(也就是你要的
Function.toDecimal(input.a.b),7.2)。 - 递归嵌套处理:通过
extractInnerFunctions方法,自动识别并提取内部的嵌套函数(比如Function.toDecimal(input.a.b)),如果有更深层级的嵌套也能处理。
运行代码后输出:
分词结果: Function.greaterThan(Function.toDecimal(input.a.b),7.2) Function.toDecimal(input.a.b),7.2 Function.toDecimal(input.a.b)
如果你只需要前两个结果,删掉递归调用的部分即可。
注意事项
- 示例默认函数名由字母、数字和点(
.)组成,如果你有其他合法字符(比如下划线),可以调整判断函数起始位置的逻辑。 - 如果输入有多个顶级函数(比如
FuncA() + FuncB(FuncC())),可以修改代码遍历整个字符串,批量提取所有顶级函数。
内容的提问来源于stack exchange,提问作者ashok
相关产品推荐
相关产品推荐

