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

如何捕获带嵌套括号的正则模式?Java实现多级嵌套函数分词

处理Java中嵌套函数的分词问题

普通正则表达式确实搞不定嵌套括号的场景——你用的\(([^\)]+)\)会在遇到第一个右括号就停止匹配,根本识别不了嵌套层级。要解决这个问题,我们可以用**栈(Stack)**来跟踪括号深度,手动遍历字符串定位完整的函数调用,甚至递归处理内部的嵌套结构。

核心思路

  1. 遍历字符串,识别函数调用的起始位置(比如以Function.开头的标识符,或者更通用的,找到左括号(前的合法函数名)。
  2. 用栈记录括号层级:遇到(就入栈,遇到)就出栈,当栈深度回到0时,说明找到了一个完整的函数调用结束位置。
  3. 对于函数内部的参数内容,可以继续递归处理,提取嵌套的内层函数或其他内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:49:15