当前位置:  开发笔记 > 编程语言 > 正文

.NET中是否有字符串数学计算器?

如何解决《.NET中是否有字符串数学计算器?》经验,为你挑选了9个好方法。

如果我有一个带有有效数学表达式的字符串,例如:

String s = "1 + 2 * 7";

在.NET中是否有内置的库/函数来解析和评估该表达式并返回结果?在这种情况下15.



1> Tim Schmelte..:

奇怪的是,这个着名的老问题没有一个答案暗示内在DataTable.Compute- "诡计".这里是.

double result = Convert.ToDouble(new DataTable().Compute("1 + 2 * 7", null));

表达式支持以下算术运算符:

+ (addition)
- (subtraction)
* (multiplication)
/ (division)
% (modulus)

更多信息:DataColumn.Expression表达式语法.



2> user21826..:

您可以添加对Microsoft脚本控件库(COM)的引用,并使用这样的代码来计算表达式.(也适用于JScript.)

Dim sc As New MSScriptControl.ScriptControl()
sc.Language = "VBScript"
Dim expression As String = "1 + 2 * 7"
Dim result As Double = sc.Eval(expression)

编辑 - C#版本.

MSScriptControl.ScriptControl sc = new MSScriptControl.ScriptControl();
sc.Language = "VBScript";
string expression = "1 + 2 * 7";
object result = sc.Eval(expression);            
MessageBox.Show(result.ToString());

编辑 - ScriptControl是一个COM对象.在项目的"添加引用"对话框中,选择"COM"选项卡并向下滚动到"Microsoft Script Control 1.0"并选择"确定".


尽管这已被标记为答案,但那是10年前的事了,COM现在已经死了。我更喜欢下面的DataTable.Compute答案。

3> Guy..:

对于在Silverlight上使用C#开发的任何人来说,这是一个非常巧妙的技巧,我刚刚发现它允许通过调用Javascript引擎来评估表达式:

double result = (double) HtmlPage.Window.Eval("15 + 35");


@jjerry,这是因为具有前导零的数字被JS的评估者视为八进制,而八进制054等于十进制44.
由于这会评估任意Javascript代码,您可能希望确保清理输入并确保不直接显示结果.(我认为这将是一个很好的方式来引入XSS而没有意识到它)

4> GreyCloud..:

你见过http://ncalc.codeplex.com吗?

它的可扩展性,快速性(例如,具有自己的缓存)使您能够通过处理EvaluateFunction/EvaluateParameter事件在运行时提供自定义函数和变量.它可以解析的示例表达式:

Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)"); 

  e.Parameters["Pi2"] = new Expression("Pi * Pi"); 
  e.Parameters["X"] = 10; 

  e.EvaluateParameter += delegate(string name, ParameterArgs args) 
    { 
      if (name == "Pi") 
      args.Result = 3.14; 
    }; 

  Debug.Assert(117.07 == e.Evaluate()); 

它还可以本地处理unicode和许多数据类型.如果你想改变语法,它会附带一个鹿茸文件.还有一个支持MEF加载新功能的fork.



5> cbp..:

实际上有一种内置的 - 你可以使用XPath命名空间!虽然它需要您重新格式化字符串以使用XPath表示法进行确认.我使用这样的方法来处理简单的表达式:

    public static double Evaluate(string expression)
    {
        var xsltExpression = 
            string.Format("number({0})", 
                new Regex(@"([\+\-\*])").Replace(expression, " ${1} ")
                                        .Replace("/", " div ")
                                        .Replace("%", " mod "));

        return (double)new XPathDocument
            (new StringReader(""))
                .CreateNavigator()
                .Evaluate(xsltExpression);
    }



6> schoetbi..:

最初我使用了c#wrapper for muparser.这非常快.我知道的唯一更快的解决方案是exprtk.如果您正在寻找其他解决方案,您可以查看基准.

但是对于.Net,您可以使用内置支持在运行时编译代码.我们的想法是将"模板"源文件作为例如嵌入式资源,您可以在其中替换评估公式.然后将这个准备好的类源代码传递给编译器.

基本模板可能如下所示:

public class CSCodeEvaler
{
    public double EvalCode()
    {
        return last = Convert.ToDouble(%formula%);
    }

    public double last = 0;
    public const double pi = Math.PI;
    public const double e = Math.E;
    public double sin(double value) { return Math.Sin(value); }
    public double cos(double value) { return Math.Cos(value); }
    public double tan(double value) { return Math.Tan(value); }
    ...

注意表达式将放入的%formula%.

要编译,请使用CSharpCodeProvider类.我不想在这里填写完整的来源.但这个答案可能有所帮助:

加载内存程序集后,您可以创建类的实例并调用EvalCode.



7> Leroy Kegan..:

最近我使用的是mXparser,它是.NET和JAVA的数学解析器库.mXparser支持基本公式以及非常奇特/复杂的公式(包括变量,函数,运算符,迭代和递归).

https://mxparser.codeplex.com/

http://mathparser.org/

一些用法示例:

例1:

Expression e = new Expression("1+2*7 + (sin(10) - 2)/3");
double v = e.calculate();

例2:

Argument x = new Argument("x = 5");
Expression e = new Expression("2*x+3", x);
double v = e.calculate();

例3:

Function f = new Function("f(x,y) = sin(x) / cos(y)");
Expression e = new Expression("f(pi, 2*pi) - 2", f);
double v = e.calculate();

最好的祝福



8> Crowcoder..:

罗斯林可用的另一个选择是:

您可以使用CodeAnalysis.CSharp.Scripting库.

using Microsoft.CodeAnalysis.CSharp.Scripting;
using System;

namespace ExpressionParser
{
    class Program
    {
        static void Main(string[] args)
        {
            //Demonstrate evaluating C# code
            var result = CSharpScript.EvaluateAsync("System.DateTime.Now.AddDays(-1) > System.DateTime.Now").Result;
            Console.WriteLine(result.ToString());

            //Demonstrate evaluating simple expressions
            var result2 = CSharpScript.EvaluateAsync(" 5 * 7").Result;
            Console.WriteLine(result2);
            Console.ReadKey();
        }
    }
}

nuget包:









9> 小智..:

如果你需要非常简单的东西,你可以使用DataTable:-)

Dim dt As New DataTable
dt.Columns.Add("A", GetType(Integer))
dt.Columns.Add("B", GetType(Integer))
dt.Columns.Add("C", GetType(Integer))
dt.Rows.Add(New Object() {12, 13, DBNull.Value})

Dim boolResult As Boolean = dt.Select("A>B-2").Length > 0

dt.Columns.Add("result", GetType(Integer), "A+B*2+ISNULL(C,0)")
Dim valResult As Object = dt.Rows(0)("result")

推荐阅读
手机用户2402852387
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有