C# 实现Eval(字符串表达式) C# 实现Eval(字符串表达式)的三种方法
五维思考 人气:0想了解C# 实现Eval(字符串表达式)的三种方法的相关内容吗,五维思考在本文为您仔细讲解C# 实现Eval(字符串表达式)的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:C#,实现Eval,c#,实现字符串表达式,下面大家一起来学习吧。
一、背景
假如给定一个字符串表达式"-12 * ( - 2.2 + 7.7 ) - 44 * 2"
,让你计算结果,熟悉JavaScript的都知道有个Eval
函数可以直接进行计算,而C#中却没有这个函数,下面提供三种实现方式
二、代码
public class Class1 { #region 方法一:利用CodeCom [Obsolete] System.CodeDom.Compiler.ICodeCompiler comp = new Microsoft.CSharp.CSharpCodeProvider().CreateCompiler(); System.CodeDom.Compiler.CompilerParameters cp = new System.CodeDom.Compiler.CompilerParameters(); public object Eval_1(string Expression) { StringBuilder code = new StringBuilder(); code.Append("using System; \n"); code.Append("namespace ADOGuy { \n"); code.Append(" public class _Evaluator { \n"); code.Append(" public object __foo() "); code.Append("{ "); code.AppendFormat(" return ({0}); ", Expression); code.Append("}\n"); code.Append("} }"); System.CodeDom.Compiler.CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString()); System.Reflection.Assembly a = cr.CompiledAssembly; object _Compiled = a.CreateInstance("ADOGuy._Evaluator"); System.Reflection.MethodInfo mi = _Compiled.GetType().GetMethod("__foo"); return mi.Invoke(_Compiled, null); } #endregion #region 方法二:对表达式分析 string Precede(string p, string q) { switch (p) { case "+": case "-": return ("*/(".IndexOf(q) != -1) ? "<" : ">"; case "*": case "/": return (q == "(") ? "<" : ">"; case "(": return (q == ")") ? "=" : "<"; case ")": return (q == "(") ? "?" : ">"; case "#": return (q == "#") ? "=" : "<"; } return "?"; } Double Operate(Double a, char o, Double b) { switch (o) { case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': return a / b; } return 0; } public Object Eval_2(string Expression) { Stack nArr = new Stack(), oArr = new Stack(); int j = 0; Double a = 0, b = 0; string w = ""; char o; MatchCollection arr = Regex.Matches(Expression.Replace(" ", "") + "#", @"(((?<=(^|\())-)?\d+(\.\d+)?|\D)"); oArr.Push('#'); w = Convert.ToString(arr[j++]); while (!(w == "#" && Convert.ToString(oArr.Peek()) == "#")) { if ("+-*/()#".IndexOf(w) != -1) { switch (Precede(oArr.Peek().ToString(), w)) { case "<": oArr.Push(w); w = Convert.ToString(arr[j++]); break; case "=": oArr.Pop(); w = Convert.ToString(arr[j++]); break; case ">": o = Convert.ToChar(oArr.Pop()); b = Convert.ToDouble(nArr.Pop()); a = Convert.ToDouble(nArr.Pop()); nArr.Push(Operate(a, o, b)); break; default: return "Error"; } } else { nArr.Push(w); w = Convert.ToString(arr[j++]); } } return nArr.Pop(); } #endregion #region 方法三:利用JScript的Eval //需要引用Microsoft.JScript [Obsolete] readonly Microsoft.JScript.Vsa.VsaEngine ve = Microsoft.JScript.Vsa.VsaEngine.CreateEngine(); [Obsolete] public object Eval_3(string Expression) { return Microsoft.JScript.Eval.JScriptEvaluate(Expression, ve); } #endregion }
三、测试
static void Main(string[] args) { String strExpression = "-12 * ( - 2.2 + 7.7 ) - 44 * 2"; var obj = new Class1(); Console.WriteLine($"方法一(CodeCom法)计算结果:{obj.Eval_1(strExpression)}"); Console.WriteLine($"方法二(分析法)计算结果:{obj.Eval_2(strExpression)}"); Console.WriteLine($"方法三(JScript法)计算结果:{obj.Eval_3(strExpression)}"); Console.ReadLine(); }
运行结果:
方法一(CodeCom法)计算结果:-154
方法二(分析法)计算结果:-154
方法三(JScript法)计算结果:-154
加载全部内容