Regex für die Zuordnung von Funktionen und die Erfassung ihrer Argumente

Ich arbeite an einem Taschenrechner und er nimmt Zeichenkettenausdrücke und wertet sie aus. Ich habe eine Funktion, die den Ausdruck mit Regex nach mathematischen Funktionen durchsucht, die Argumente abruft, den Funktionsnamen nachschlägt und auswertet. Ich habe ein Problem damit, dass ich das nur tun kann, wenn ich weiß, wie viele Argumente es geben wird. Ich kann den Regex nicht richtig verstehen. Und wenn ich nur den Inhalt der( und) Zeichen von der, Zeichen, dann kann ich keine anderen Funktionsaufrufe in diesem Argument haben.

Hier ist das Funktionsmuster:\b([a-z][a-z0-9_]*)\((..*)\)\b

Es funktioniert nur mit einem Argument. Kann ich für jedes Argument eine Gruppe erstellen, mit Ausnahme der Argumente in verschachtelten Funktionen? Zum Beispiel würde es passen:func1(2 * 7, func2(3, 5)) und erstellen Sie Erfassungsgruppen für:2 * 7 undfunc2(3, 5)

Hier die Funktion, mit der ich den Ausdruck auswerte:

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

Wie Sie sehen, gibt es einen ziemlich schlechten Versuch, einen Regex zu erstellen, der den Argumenten entspricht. Es funktioniert nicht

Ich versuche nur zu extrahieren2 * 7 undfunc2(3, 5) aus dem Ausdruckfunc1(2 * 7, func2(3, 5)) Es muss aber auch für Funktionen mit unterschiedlichen Argumenten funktionieren. Wenn es einen Weg gibt, dies ohne Regex zu tun, ist das auch gut.

Antworten auf die Frage(5)

Ihre Antwort auf die Frage