Regex для сопоставления функций и захвата их аргументов

Я работаю над калькулятором, и он принимает строковые выражения и оценивает их. У меня есть функция, которая ищет выражение для математических функций с использованием Regex, получает аргументы, ищет имя функции и оценивает его. У меня проблемы с тем, что я могу сделать это только, если я знаю, сколько аргументов будет, я не могу понять Regex правильно. И если я просто разделю содержимое( а также) символы по, символ, то я не могу иметь другие вызовы функций в этом аргументе.

Вот образец соответствия функции:\b([a-z][a-z0-9_]*)\((..*)\)\b

Он работает только с одним аргументом. Могу ли я создать группу для каждого аргумента, исключая аргументы внутри вложенных функций? Например, это будет соответствовать:func1(2 * 7, func2(3, 5)) и создать группы захвата для:2 * 7 а такжеfunc2(3, 5)

Вот функция, которую я использую для оценки выражения:

    /// <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_]*)\((..*)\)");

Как вы можете видеть, есть довольно неудачная попытка построить регулярное выражение для соответствия аргументам. Не работает

Все, что я пытаюсь сделать, это извлечь2 * 7 а такжеfunc2(3, 5) из выраженияfunc1(2 * 7, func2(3, 5)) но это должно работать и для функций с различным количеством аргументов. Если есть способ сделать это без использования Regex, это тоже хорошо.

Ответы на вопрос(5)

Ваш ответ на вопрос