将表达式从文本框转换为代码隐藏中的数学表达式

时间:2012-10-25 15:18:40

标签: c# math equation equations

  

可能重复:
  I need a fast runtime expression parser

如果有人在我的网页上的文本框中输入 x * y ^ z 来计算后面代码中的公式并获得结果,该怎么做呢?

6 个答案:

答案 0 :(得分:5)

.NET没有用于评估任意字符串的内置函数。但是,名为NCalc的开源.NET库可以。

  

NCalc是.NET中的数学表达式计算器。 NCalc可以解析   任何表达式并评估结果,包括静态或动态   参数和自定义函数。

答案 1 :(得分:4)

用户operators as stringshttps://stackoverflow.com/users/1670022/matt-crouch回答:

“如果您只需要简单算术,请执行此操作。

    DataTable temp = new DataTable();
    Console.WriteLine(temp.Compute("15 / 3",string.Empty));
编辑:更多信息。查看MSDN文档,了解System.Data.DataColumn类的Expression属性。 “表达式语法”中的内容概述了除算术运算符外还可以使用的命令列表。 (例如,IIF,LEN等)。“

答案 2 :(得分:3)

这个问题有两种主要方法,每种方法都有一些变化,如各种答案所示。

  • 选项A:找一个现有的数学表达评估员
  • 选项B:编写自己的解析器和计算结果的逻辑

在详细讨论这个问题之前,强调解释任意数学表达式不是一项微不足道的任务,对于任何表达式语法,除了"玩具"这些语法只接受一个或两个算术运算,不允许括号等。

理解这样的任务是微不足道的,并且承认,毕竟解释平均复杂度的算术表达式是对各种应用程序的相对经常性的需求[因此应该提供成熟的解决方案],尝试可能是明智的并使用"选项A"  因此,我第二次推荐了一个现成的表达式评估器,例如 NCalc

然而,花费时间并理解与解析和解释算术表达式相关的各种概念和方法可能是有用的,就好像有人想要掀起一个人自己的实现

关键概念是formal grammar。求值程序将接受的算术表达式必须遵循一组规则,例如允许的算术运算列表。例如,评估者会支持三角函数,或者如果它支持,它还会包括说 atan2()。规则还指出构成操作数的内容,例如,允许输入与45位数一样大的数值。关键在于所有这些规则都是用语法形式化的。

通常,语法适用于先前从原始输入文本中提取的 标记 。基本上在该过程的某个时间,某些逻辑需要分析输入字符串,逐个字符,并确定哪些字符序列组合在一起。例如,在123 + 45 / 9.3表达式中,标记是整数值123plus运算符,整数值45division运算符,最后是9.3真正的价值。识别令牌并将其与令牌类型相关联的任务是作业lexer。词法分析器可以建立他们自己上的语法(语法其中"令牌"是单个字符,而不是在语法用于算术表达式分析器哪些记号是由词法分析器产生的短字符串)

BTW,语法用于定义除算术表达式之外的许多其他东西。计算机语言遵循[相当sophiticated]语法,但引入 域特定语言 又称DSL以支持计算机应用程序的各种功能是相对常见的。

对于非常简单的语法,可以从头开始编写相应的词法分析器和解析器。但是,语法很快就会变得复杂到手写这些模块变得挑剔,容易出错并且可能更难以阅读的程度。因此Lexer and Parser Generators的存在是独立的程序,它们从规则列表中生成词法分析器和解析器的代码(在特定的编程语言中,如C,Java或C#)(以特定于语法的语法表示)生成器,虽然许多生成器倾向于使用类似的语法,松散地基于BNF)。

使用这样的词法分析器/解析器生成器时,可以通过多个步骤完成工作:
   - 第一个写出语法的定义(以特定于生成器的语言/语法)
   - 一个人通过发电机运行这个语法    - 一个人经常多次重复上述两个步骤,因为写一个语法是一个严格的练习:生成器会抱怨可能写入语法的许多可能的含糊之处。
   - 最终生成器生成一个源文件(以所需的目标语言,如C#等)    - 此来源包含在整个项目中    - 项目中的其他源文件可以调用生成器生成的源文件中公开的函数和/或与解析期间识别的各种模式对应的某些逻辑可以很容易地嵌入到生成器生成的代码中。    - 然后可以像往常一样构建项目,即好像解析器和词法分析器是手写的。

关于使用正式语法和代码生成器进行 20,000英尺高的过程的介绍。 可以在此link找到解析器生成器列表(也称为编译器编译器)。对于C#中的简单工作,我还想提一下Irony。仔细阅读这些网站可能会非常有见地,以便更好地了解这些概念,即使目前没有成为从业者的意图。
如上所述,我想强调的是,对于这个特定的应用,,现成的算术评估器可能是更好的方法。这些的主要缺点是

  • 关于允许的表达式语法是什么的一些限制(允许的语法限制太多:你还需要说stddev()或太宽泛:你不希望你的用户使用trig函数。更成熟的评估者,会有某种形式的配置/扩展功能,可以解决这个问题。
  • 这样的第三方模块的学习曲线。希望他们中的许多人应该相对"即插即用"。

答案 3 :(得分:1)

使用此库http://www.codeproject.com/Articles/21137/Inside-the-Mathematical-Expressions-Evaluator

解决了

我的最终代码

Calculator Cal = new Calculator();
txt_LambdaNoot.Text = (Cal.Evaluate(txt_C.Text) / fo).ToString();

现在当某个类型3 * 10 ^ 11时他将获得300000000000

答案 4 :(得分:0)

你需要的是 - 如果你想自己做 - 在后面的代码中是 Scanner (also known as Lexer) + Parser 来解释表达式。或者,您可以找到第三方库来完成工作,其工作方式与JavaScript eval(string)函数类似。

请查看here,它描述了递归下降解析器。该示例使用 C 编写,但是一旦您了解了本文中描述的想法,您就应该能够轻松地将其调整为 C#

它没有听起来那么复杂,特别是如果你需要支持的运营商数量有限。

优势在于您可以完全控制将执行的表达式(以防止您网站的最终用户注入恶意代码)。

答案 5 :(得分:0)

您需要实现(或查找第三方源)表达式解析器。这是一件微不足道的事情。