Regex do dopasowywania funkcji i przechwytywania ich argumentów

Pracuję nad kalkulatorem i pobiera wyrażenia łańcuchowe i je ocenia. Mam funkcję, która przeszukuje wyrażenie funkcji matematycznych za pomocą Regex, pobiera argumenty, wyszukuje nazwę funkcji i ocenia ją. Mam problem z tym, że mogę to zrobić tylko wtedy, gdy wiem, ile będzie argumentów, nie mogę uzyskać prawa Regex. A jeśli po prostu podzielę zawartość( i) postacie wg, wtedy nie mogę mieć innych wywołań funkcji w tym argumencie.

Oto wzór dopasowania funkcji:\b([a-z][a-z0-9_]*)\((..*)\)\b

Działa tylko z jednym argumentem, czy mogę utworzyć grupę dla każdego argumentu, wyłączając te wewnątrz funkcji zagnieżdżonych? Na przykład pasowałoby do:func1(2 * 7, func2(3, 5)) i twórz grupy przechwytywania dla:2 * 7 ifunc2(3, 5)

Tutaj używam funkcji do oceny wyrażenia:

    /// <summary>
    /// Attempts to evaluate and store the result of the given mathematical expression.
    /// </summary>
    public static bool Evaluate(string expr, ref double result)
    {
        expr = expr.ToLower();

        try
        {
            // Matches for result identifiers, constants/variables objects, and functions.
            MatchCollection results = Calculator.PatternResult.Matches(expr);
            MatchCollection objs = Calculator.PatternObjId.Matches(expr);
            MatchCollection funcs = Calculator.PatternFunc.Matches(expr);

            // Parse the expression for functions.
            foreach (Match match in funcs)
            {
                System.Windows.Forms.MessageBox.Show("Function found. - " + match.Groups[1].Value + "(" + match.Groups[2].Value + ")");

                int argCount = 0;
                List<string> args = new List<string>();
                List<double> argVals = new List<double>();
                string funcName = match.Groups[1].Value;

                // Ensure the function exists.
                if (_Functions.ContainsKey(funcName)) {
                    argCount = _Functions[funcName].ArgCount;
                } else {
                    Error("The function '"+funcName+"' does not exist.");
                    return false;
                }

                // Create the pattern for matching arguments.
                string argPattTmp = funcName + "\\(\\s*";

                for (int i = 0; i < argCount; ++i)
                    argPattTmp += "(..*)" + ((i == argCount - 1) ? ",":"") + "\\s*";
                argPattTmp += "\\)";

                // Get all of the argument strings.
                Regex argPatt = new Regex(argPattTmp);

                // Evaluate and store all argument values.
                foreach (Group argMatch in argPatt.Matches(match.Value.Trim())[0].Groups)
                {
                    string arg = argMatch.Value.Trim();
                    System.Windows.Forms.MessageBox.Show(arg);

                    if (arg.Length > 0)
                    {
                        double argVal = 0;

                        // Check if the argument is a double or expression.
                        try {
                            argVal = Convert.ToDouble(arg);
                        } catch {
                            // Attempt to evaluate the arguments expression.
                            System.Windows.Forms.MessageBox.Show("Argument is an expression: " + arg);

                            if (!Evaluate(arg, ref argVal)) {
                                Error("Invalid arguments were passed to the function '" + funcName + "'.");
                                return false;
                            }
                        }

                        // Store the value of the argument.
                        System.Windows.Forms.MessageBox.Show("ArgVal = " + argVal.ToString());
                        argVals.Add(argVal);
                    }
                    else
                    {
                        Error("Invalid arguments were passed to the function '" + funcName + "'.");
                        return false;
                    }
                }

                // Parse the function and replace with the result.
                double funcResult = RunFunction(funcName, argVals.ToArray());
                expr = new Regex("\\b"+match.Value+"\\b").Replace(expr, funcResult.ToString());
            }

            // Final evaluation.
            result = Program.Scripting.Eval(expr);
        }
        catch (Exception ex)
        {
            Error(ex.Message);
            return false;
        }

        return true;
    }

    ////////////////////////////////// ---- PATTERNS ---- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

    /// <summary>
    /// The pattern used for function calls.
    /// </summary>
    public static Regex PatternFunc = new Regex(@"([a-z][a-z0-9_]*)\((..*)\)");

Jak widzisz, istnieje dość zła próba zbudowania Regexu, aby dopasować argumenty. To nie działa.

Wszystko, co próbuję zrobić, to wyciąg2 * 7 ifunc2(3, 5) z wyrażeniafunc1(2 * 7, func2(3, 5)) ale musi działać również dla funkcji z różnymi licznikami argumentów. Jeśli istnieje sposób, aby to zrobić bez użycia Regex, jest to również dobre.

questionAnswers(5)

yourAnswerToTheQuestion