NCalc库 解析并计算字符串数学表达式

NCalc 库

该框架用于计算字符串表达式

安装 NuGet 包

NCalc.NetCore

简单使用方式,直接传入表达式

var res = new Expression("4+4").Evaluate();

Console.WriteLine(res);
Console.ReadKey();

方法 Evaluate() 的用处

该方法用于计算结果,返回计算的结果,返回值为 object 类型

处理 Math 类所支持的函数

  • Abs:返回指定数字的绝对值。
  • Acos :返回余弦为指定数字的角度。
  • Asin :返回正弦为指定数字的角度。
  • Atan :返回其切线为指定数字的角度。
  • Ceiling :返回大于或等于指定数字的最小整数。
  • Cos :返回指定角度的余弦值。
  • Exp :返回 e 提高到指定幂。
  • Floor :返回小于或等于指定数字的最大整数。
  • IEEERemainder :返回将指定数字除以另一个指定数字所产生的余数。两个参数
  • Log :返回指定数字的对数。两个参数,第一个参数是指定的值,第二个参数是指定的对数
  • Log10 :返回指定数字的 10 进制对数。
  • Max :返回两个指定数字中的较大者。两个参数
  • Min :返回两个数字中的较小者。两个参数
  • Pow :返回提高到指定幂的指定数字。两个参数,第一个参数是幂数,第二个参数是指定数字
  • Round :将值舍入到最接近的整数或指定的小数位数。
  • Sign :返回一个值,该值指示数字的符号。
  • Sin :返回指定角度的正弦波。
  • Sqrt :返回指定数字的平方根。
  • Tan :返回指定角度的切线。
  • Truncate :计算数字的整数部分。

自定义函数

如果使用了 NCalc 库中没有的内置函数,就会直接抛出异常,可以通过自定义函数来解决这个问题

使用自定义函数时:

  1. 调用 EvaluateFunction 事件,该事件有两个参数,无返回值
  2. 参数 1 为 string 类型,表示自定义函数的名称
  3. 参数 2 为 FunctionArgs 类型,包含自定义函数中的参数,以及计算结果,FunctionArgs 中包含以下成员
    • Parameters:Expression[] 类型,函数中的参数数组
    • Result:将计算结果赋值给该属性,该属性会将结果与表达式中自定义函数进行替换,完成计算
    • EvaluateParameters():方法会将 Parameters 中的每个成员调用 Evaluate() 方法进行计算,因为 Parameters 的成员是 Expression 类型,所以使用时要先计算在使用
var e = new Expression("ln(10)+ln(1)");
e.EvaluateFunction += (string name, FunctionArgs args) =>
{
    if (name == "ln")
    {
        if (double.TryParse(args.Parameters[0].Evaluate().ToString(), out var param))
        {
            args.Result = Math.Log(param);
        }
    }
};

Console.WriteLine(e.Evaluate());
Console.ReadKey();

自定义参数(两种参数:静态参数和动态参数)
(1) 静态参数:直接将自定义参数添加到参数字典中(常用)

var e = new Expression("x+y");
e.Parameters["x"] = 1;
e.Parameters["y"] = 2;

Console.WriteLine(e.Evaluate());
Console.ReadKey();

(2) 动态参数:主要处理比较复杂的参数,使用 EvaluateParameter 事件

  1. 调用 EvaluateParameter 事件,该事件有两个参数,无返回值
  2. 参数 1 为 string 类型,表示自定义函数的名称
  3. 参数 2 为 ParameterArgs 类型,ParameterArgs 中包含以下成员
    • Result:将计算结果赋值给该属性,该属性会将结果与表达式中自定义函数进行替换,完成计算
var e = new Expression("x+y");
e.EvaluateParameter += (string name, ParameterArgs args) =>
{
    if (name == "x")
    {
        args.Result = 1;
    }
    else if (name == "y")
    {
        args.Result = 2;
    }
};

Console.WriteLine(e.Evaluate());
Console.ReadKey();

两种方式的结果都是一样的

区分大小写

默认情况下表达式是区分大小写的,参数或者函数名要完全匹配,可以设置参数使用 EvaluateOptions 枚举设置为 IgnoreCase 表示不区分大小写

 var e = new Expression("X+y", EvaluateOptions.IgnoreCase);

 e.Parameters["x"] = 1;
 e.Parameters["y"] = 2;

 Console.WriteLine(e.Evaluate());
 Console.ReadKey();

var e1 = new Expression("Log(10,10)", EvaluateOptions.IgnoreCase);
var e2 = new Expression("log(10,10)", EvaluateOptions.IgnoreCase);

Console.WriteLine(e1.Evaluate());
Console.WriteLine(e2.Evaluate());
Console.ReadKey();

注意:自定义参数的第二种写法是区分大小写的,即使设置了该枚举也会区分大小写(只有这一种情况是完全区分大小写的)

异常处理(两种方式)

(1) 使用 try-catch

当表达式存在语法错误时,计算将抛出异常,异常的类型为 EvaluationException

try
{
    new Expression("(3 + 2").Evaluate();
}
catch(EvaluationException e)
{
    Console.WriteLine(e.Message);
}

(2) 使用 HasErrors() 方法在计算之前检测语法错误。

Expression e = new Expression("a + b * (");
if(e.HasErrors())
{
    Console.WriteLine(e.Error);
}
posted @ 2023-09-27 17:10  青蛙001  阅读(2915)  评论(0)    收藏  举报