【问题标题】:How to evaluate custom parenthesis expression in C#?如何在 C# 中评估自定义括号表达式?
【发布时间】:2016-04-22 07:26:38
【问题描述】:

我正在开发一个高级搜索功能,我需要评估的表达式看起来像这样,带有括号:

((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).

如果我们看括号,必须先计算条件 1 和条件 2,然后使用条件 3 执行 this 的输出,依此类推......

我们有 API 可以一次评估两个条件。然而,在这种情况下的挑战是

1) 如何识别相应的括号并首先对其进行评估。然后用这个中间结果做进一步的评估?

2)如何找到未使用的括号?例如 (((condition1 And condition2))),在这种情况下,虽然它不是必需的,但有 3 个开始和 3 个结束括号,这是一个有效的表达式。

我试图找到一些算法herehere

但是,这需要基于令牌的操作,一次读取一个字符,并且它是计算机理解的算术表达式评估。在我的情况下,这些东西是定制的,我们应该找到一个算法来做到这一点。任何人都可以为我的方案提出更好的方法吗?

【问题讨论】:

  • 我会将表达式树与您的 api 一起使用(如果您不想自己创建表达式树,也可以使用 linqkit,尽管它们看起来相当简单)
  • 您的表达式需要一个解析器。下面是如何构建一个:stackoverflow.com/questions/2245962/… 那篇文章将向您展示如何构建树以允许以后进行评估,或者如何在解析表达式时对其进行评估。
  • 分流码算法允许您将中缀表示法转换为后缀表示法,其中“内部”运算符简单地位于“外部”运算符之前。您可以像那些文章那样评估结果,但您也可以将其转换为 AST,或您的 API 需要的任何格式。那么...您的 API 需要什么格式?

标签: c# regex algorithm parsing expression


【解决方案1】:

如果我理解正确,你已经得到了表达式评估器。您需要的是根据括号拆分评估。我会使用一个循环,我会在其中找到内括号组,使用这个正则表达式:

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

然后,如果找到,将它们替换为您的评估例程的结果,并重复直到剩下最后一个字符串,不带括号。

伪代码:

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

关于 unused 括号,让他们一视同仁。它们最终会作为单个值出现在您的评估例程中。

Check this fiddle。它不会评估它返回一个随机数01,但它演示了逻辑。

希望这会有所帮助。

问候。

【讨论】:

  • 在我看来,正则表达式不是为解析语法递归表达式而设计的。例如可以(部分)选择字符串,但没有评估,通信错误....
  • @JacekCz 我同意(在某种程度上 - 我经常将正则表达式用于简单的评估任务)。而且我在这里提出的解决方案不使用正则表达式进行评估。它只是识别需要评估的部分
  • 感谢 Clas,这为我奠定了基础。
  • @ClasG,在上述情况下,如果中间条件评估的输出返回复杂对象而不是字符串,应该采取什么方法?
  • 您提到我们有API 可以同时评估两个条件,我猜您发送给它的内容类似于Loan number is 1000 And Lock Date is less than 12/03/2015,但输出是什么?我假设这就是你所说的复杂对象 - 所以你的 API 进程不能[complex object] Or Borrower SSN contains 12345
猜你喜欢
  • 1970-01-01
  • 2011-02-08
  • 2016-05-04
  • 1970-01-01
  • 2014-10-03
  • 2013-06-20
  • 2018-12-13
  • 1970-01-01
相关资源
最近更新 更多