简体   繁体   中英

How validate a logical expression using Regular expression Or C#

I need to validate the Logical Expressions like,

( ( var1 == var2 ) && ( var2 >= var4 || var1 > var5 ) )

( var1 < var2 ) 

( var1 == var2 || var3 != var4 )

Each braces, variables and logical operator are separated by single SPACE.

I need a regular expression to parse it.

Or tell me some logic to validate this with C#.

Thanks.

Either build your own parser, or see below (found here ). You'll need to change it a bit to account for variables, but that shouldn't be too hard. Either, parse them before passing them to the function, or change the function to except variable names and values.

    using System.CodeDom.Compiler;
    using Microsoft.CSharp;
    using System.Reflection;
    /// <summary>
    /// A simple function to get the result of a C# expression (basic and advanced math possible)
    /// </summary>
    /// <param name="command">String value containing an expression that can evaluate to a double.</param>
    /// <returns>a Double value after evaluating the command string.</returns>
    private double ProcessCommand(string command)
    {
        //Create a C# Code Provider
        CSharpCodeProvider myCodeProvider = new CSharpCodeProvider();
        // Build the parameters for source compilation.
        CompilerParameters cp = new CompilerParameters();
        cp.GenerateExecutable = false;//No need to make an EXE file here.
        cp.GenerateInMemory = true;   //But we do need one in memory.
        cp.OutputAssembly = "TempModule"; //This is not necessary, however, if used repeatedly, causes the CLR to not need to 
                                          //load a new assembly each time the function is run.
        //The below string is basically the shell of a C# program, that does nothing, but contains an
        //Evaluate() method for our purposes.  I realize this leaves the app open to injection attacks, 
        //But this is a simple demonstration.
        string TempModuleSource = "namespace ns{" +
                                  "using System;" +
                                  "class class1{" +
                                  "public static double Evaluate(){return " + command + ";}}} ";  //Our actual Expression evaluator

        CompilerResults cr = myCodeProvider.CompileAssemblyFromSource(cp,TempModuleSource);
        if (cr.Errors.Count > 0)
        {
            //If a compiler error is generated, we will throw an exception because 
            //the syntax was wrong - again, this is left up to the implementer to verify syntax before
            //calling the function.  The calling code could trap this in a try loop, and notify a user 
            //the command was not understood, for example.
            throw new ArgumentException("Expression cannot be evaluated, please use a valid C# expression");
        }
        else
        {
            MethodInfo Methinfo = cr.CompiledAssembly.GetType("ns.class1").GetMethod("Evaluate");
            return (double)Methinfo.Invoke(null, null);
        }
    } 

If I were doing this and I wanted to do it as a regex, I would create a multipass algorithm with each pass eliminating a validated subcase (eg replace a validated "( x == y )" with "x"

Perhaps something starting with: s/\\b\\w+ $op \\w+\\b/^^MAGICTOKEN^^/g

Then any /$op/ would be illegal.

Then focus in a loop on each paren: s/\\(( [^\\)]+ )\\)/^^MAGICTOKEN^^/

While focused on $1, reduce: s/ $MAGICTOKRE $BOOL $MAGICTOKRE / ^^MAGICTOKEN^^ / Run the reduce in a loop until it stops reducing. If $1 ne " ^^MAGICTOKEN^^ " , error

After the focus loop, most likely $expression ne "^^MAGICTOKEN^^" would indicate an error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM