C# - 解析包含逻辑运算符的复杂字符串

发布于 2025-01-01 04:25:27 字数 382 浏览 2 评论 0原文

我从其他人编写的配置文件中读取了一个逻辑字符串,其中包含如下表达式:

(VALUE_1)OR((NOT(VALUE_2))AND(NOT(VALUE_3)))

但是,我有点困惑从哪里开始解析它并比较我拥有的变量的值在其他地方存储为相同的字符串名称。我认为 LambdaExpression 是需要使用的东西是否正确?字符串是否需要以某种方式拆分并作为组成部分而不是整体进行分析?

编辑:

似乎Flee做了我需要它做的事情,我可以定义在使用该库评估表达式之前,将 VALUE_x 的名称设置为 true 或 false。

I've got a logical string read in from a configuration file written by someone else that contains expressions such as the following:

(VALUE_1)OR((NOT(VALUE_2))AND(NOT(VALUE_3)))

However, I'm a little stumped as to where to start parsing this and comparing the values of the variables that I have stored as the same string name elsewhere. Am I correct in thinking LambdaExpression is the thing that needs to be used? Does the string need splitting in some way and to be analysed as the constituent parts rather than as a whole?

EDIT:

It seems as though Flee does what I need it to do, I can define the names of the VALUE_x as true or false before evaluating the expression using that library.

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

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

发布评论

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

评论(2

一身软味 2025-01-08 04:25:27

在 C# 中计算字符串表达式的典型方法是构建表达式树并将其编译为委托(.NET 框架涵盖了这项工作)。在大多数情况下 动态 linq 库<建议使用 /a>,但它有几个缺点:它不支持作为可重用库(实际上它只是 Scott Gu 发布的 LINQ 功能的说明),并且它只能评估强类型表达式,这在大多数现实生活应用程序中都是不好的。

我建议更好的选择:来自 NReco Commons 的 lambda 表达式解析器(这是免费的开源库)。它还构建表达式树,但使用完全不同的方法来解析表达式并将其评估为表达式树:它在运行时执行所有类型的协调和调用(如动态语言),支持属性和方法调用、数组构造和条件运算符。一些示例:(

var lambdaParser = new NReco.LambdaParser();

var varContext = new Dictionary<string,object>();
varContext["pi"] = 3.14M;
varContext["one"] = 1M;
varContext["two"] = 2M;
varContext["test"] = "test";
varContext["arr1"] = new double[] { 1.5, 2.5 };
Console.WriteLine( lambdaParser.Eval("pi>one && 0<one ? (1+8)/3+1*two : 0", varContext) ); // --> 5
Console.WriteLine( lambdaParser.Eval(" arr1[0]+arr1[1] ", varContext) ); // -> 4
Console.WriteLine( lambdaParser.Eval(" (new[]{1,2})[1]  ", varContext) ); // -> 2

更多示例和文档可以在 NReco Commons 库页面找到)

Typical approach for evaluating string expressions in C# is building expression tree and compiling it into delegate (this job is covered by .NET framework). In most cases dynamic linq library is recommended but it has several drawbacks: it is not supported as reusable library (actually it is just illustration of LINQ capabilities published by Scott Gu) and it can evaluate only strongly typed expressions which is bad in most real life applications.

I suggest better alternative: lambda expressions parser from NReco Commons (this is free and open source library). It also builds expression tree but uses quite different approach to expression parsing and evaluating it as expression tree: it performs all types harmonization and invocations at runtime (like dynamic languages), supports property and methods calls, arrays construction and conditional operator. Some examples:

var lambdaParser = new NReco.LambdaParser();

var varContext = new Dictionary<string,object>();
varContext["pi"] = 3.14M;
varContext["one"] = 1M;
varContext["two"] = 2M;
varContext["test"] = "test";
varContext["arr1"] = new double[] { 1.5, 2.5 };
Console.WriteLine( lambdaParser.Eval("pi>one && 0<one ? (1+8)/3+1*two : 0", varContext) ); // --> 5
Console.WriteLine( lambdaParser.Eval(" arr1[0]+arr1[1] ", varContext) ); // -> 4
Console.WriteLine( lambdaParser.Eval(" (new[]{1,2})[1]  ", varContext) ); // -> 2

(more examples and documentation could be found at NReco Commons library page)

我的黑色迷你裙 2025-01-08 04:25:27

我认为您可以将字符串转换为单词数组,然后根据存储的变量检查每个单词。

    //Convert the string into an array of words
        string[] source = line.Split(new char[] { '.', '?', '!', ' ', ';', ',','(',')' }, StringSplitOptions.RemoveEmptyEntries);

        // Create and execute the query. It executes immediately 
        // because a singleton value is produced.
        // Use ToLowerInvariant to match "data" and "Data" 
        var matchQuery = from word in source
                         where word.ToLowerInvariant().Contains("your stored variable elsewhere")
                         select word;

        // Count the matches. 
        int varCount = matchQuery.Count();

使用匹配查询来处理匹配的变量名称。

希望这有帮助

I think you can convert string into array of words and then check each words against your stored variables.

    //Convert the string into an array of words
        string[] source = line.Split(new char[] { '.', '?', '!', ' ', ';', ',','(',')' }, StringSplitOptions.RemoveEmptyEntries);

        // Create and execute the query. It executes immediately 
        // because a singleton value is produced.
        // Use ToLowerInvariant to match "data" and "Data" 
        var matchQuery = from word in source
                         where word.ToLowerInvariant().Contains("your stored variable elsewhere")
                         select word;

        // Count the matches. 
        int varCount = matchQuery.Count();

use match query to deal with matched variable names.

Hope this helps

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