如何使用正则表达式或 C# 验证逻辑表达式

发布于 2024-11-08 18:32:10 字数 269 浏览 0 评论 0原文

我需要验证逻辑表达式,例如

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

( var1 < var2 ) 

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

每个大括号、变量和逻辑运算符均由单个空格分隔。

我需要一个正则表达式来解析它。

或者告诉我一些用 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

娇妻 2024-11-15 18:32:10

构建您自己的解析器,或参见下文(此处)。您需要对其进行一些更改以考虑变量,但这应该不会太难。要么在将它们传递给函数之前解析它们,要么将函数更改为除外变量名称和值。

    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);
        }
    } 

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);
        }
    } 
夜无邪 2024-11-15 18:32:10

如果我正在这样做并且我想将其作为正则表达式来执行,我将创建一个多遍算法,每次通过都会消除经过验证的子情况(例如,将经过验证的“( x == y )”替换为“x”

也许以以下内容开头: s/\b\w+ $op \w+\b/^^MAGICTOKEN^^/g

那么任何 /$op/ 都是非法的,

然后将焦点放在每个括号上的循环中: s /\(( [^\)]+ )\)/^^MAGICTOKEN^^/

当关注 $1 时,减少:s/ $MAGICTOKRE $BOOL $MAGICTOKRE / ^^MAGICTOKEN^^ /
循环运行reduce,直到停止reduce。
If $1 ne " ^^MAGICTOKEN^^ ", error

在焦点循环之后,$expression ne "^^MAGICTOKEN^^" 很可能指示错误。

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 (e.g. 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文