如何在C#中评估自定义括号表达式?

3

我正在开发高级搜索功能,需要评估的表达式应该是这样的(请保留括号):

((Loan number is 1000 And
Lock Date is less than 12/03/2015) Or
Borrower SSN contains 12345) And
((Buy date is between 12/01/2015 and 23/02/2016 And
APR is less than 20000) Or
Loan amount is greater than 60000)

或者简单来说
((condition1 And condition2) Or condition 3) And ((condition4 And condition5) Or condition6).

如果我们看一下括号,condition1和condition2必须先被评估,然后再将其输出结果与condition3等进行执行...
我们有API可以同时评估两个条件。然而,在这种情况下的挑战是:
1)如何识别相应的括号并首先对它们进行评估?然后使用这个中间结果进行进一步的评估?
2)如何找到未使用的括号?例如 (((condition1 And condition2))),在这种情况下,虽然不需要它,但有3个起始和3个关闭括号是一个有效的表达式。
我尝试在此处以及这里找到一些算法。
然而,这需要基于标记的操作,逐字符读取,这是计算机理解的算术表达式评估。在我的情况下,这些东西是自定义的,因此我们应该找到一个算法来解决这个问题。有人可以为我的情况建议更好的方法吗?

1
我建议您使用表达式树和您的 API(或者使用 LinqKit 如果您不想自己创建表达式树,虽然它们看起来相当简单)。 - Alexander Derck
1
你需要一个解析器来处理你的表达式。以下是如何构建一个解析器:https://dev59.com/v3E95IYBdhLWcg3wlu6z#2336769 该文章还会引导你去了解如何构建树以便后续评估,或者如何在解析时直接进行表达式的计算。 - Ira Baxter
Shunting-yard算法允许您将中缀表达式转换为后缀表达式,其中“内部”运算符仅出现在“外部”运算符之前。您可以像那些文章一样评估结果,但您也可以将其转换为AST或任何格式,以满足您的API要求。那么...您的API需要哪种格式? - Pieter Witvoet
1个回答

3

如果我理解正确,您已经获得了表达式求值器。您需要的是根据括号将评估分离。我会使用循环,在其中使用此正则表达式查找内部括号组:

\(([^()]*)\)

然后,如果找到了括号,用你的评估例程的结果替换它们,重复这个过程直到最终字符串不再含有括号。
伪代码:
Find a string enclosed by (), not containing any ()
If found
    Replace it with the evaluated value of the string (including parenthesis)
    Go again
Return result

关于未使用的括号,让它们被视为相同。它们最终将作为一个单一的值出现在您的评估程序中。
请查看此Fiddle。它返回一个随机数0或1而不是求值,但它演示了逻辑。
希望这可以帮助您。
谢谢。

1
在我看来,正则表达式并不适合解析具有语法递归性质的表达式。例如,在某些情况下可以选择字符串,但是无法对其进行评估、通信错误等操作。 - Jacek Cz
@JacekCz 我同意(在某种程度上 - 对于简单的评估任务,我经常使用正则表达式)。而我在这里提出的解决方案并不使用正则表达式进行评估。它仅仅是识别需要评估的部分 - SamWhan
谢谢 Clas,这为我奠定了基础。 - user3796454
@ClasG,在上述情况下,如果中间条件评估的输出返回一个复杂对象而不是字符串,应该采取什么方法? - user3796454
你提到了我们有API可以同时评估两个条件,我猜想你传递给API的内容类似于 贷款号为1000且锁定日期早于2015年12月3日,但是输出结果是什么呢?我猜想那就是你所说的复杂对象-所以你们的API不能处理 [复杂对象] 或者借款人社安号包含12345吗? - SamWhan
@ClasG,我已经开始处理这个问题了。实际上,我的API不能直接接受这些字符串,而是需要将它们拆分并作为适当的参数传递。随着嵌套层次的增加,处理变得更加棘手。我们需要编写一些自定义代码来构建智能性。我会处理这个问题。非常感谢你的帮助,Clas :)。 - user3796454

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接