C# 實現(xiàn)Eval(字符串表達(dá)式)的三種方法
一、背景
假如給定一個字符串表達(dá)式"-12 * ( - 2.2 + 7.7 ) - 44 * 2"
,讓你計算結(jié)果,熟悉JavaScript的都知道有個Eval
函數(shù)可以直接進(jìn)行計算,而C#中卻沒有這個函數(shù),下面提供三種實現(xiàn)方式
二、代碼
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 方法二:對表達(dá)式分析 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法)計算結(jié)果:{obj.Eval_1(strExpression)}"); Console.WriteLine($"方法二(分析法)計算結(jié)果:{obj.Eval_2(strExpression)}"); Console.WriteLine($"方法三(JScript法)計算結(jié)果:{obj.Eval_3(strExpression)}"); Console.ReadLine(); }
運行結(jié)果:
方法一(CodeCom法)計算結(jié)果:-154
方法二(分析法)計算結(jié)果:-154
方法三(JScript法)計算結(jié)果:-154
以上就是C# 實現(xiàn)Eval(字符串表達(dá)式)的三種方法的詳細(xì)內(nèi)容,更多關(guān)于C# 實現(xiàn)Eval(字符串表達(dá)式)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#調(diào)用SQL?Server中有參數(shù)的存儲過程
這篇文章介紹了C#調(diào)用SQL?Server中有參數(shù)存儲過程的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-03-03WinForm實現(xiàn)窗體最大化并遮蓋任務(wù)欄的方法
這篇文章主要介紹了WinForm實現(xiàn)窗體最大化并遮蓋任務(wù)欄的方法,涉及C#實現(xiàn)WinForm窗體全屏顯示的實現(xiàn)及調(diào)用技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-08-08C#實現(xiàn)循環(huán)發(fā)送電腦屏幕截圖
這篇文章主要為大家詳細(xì)介紹了C#實現(xiàn)循環(huán)發(fā)送電腦屏幕截圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-07-07C#實現(xiàn)對字符串中特定詞出現(xiàn)次數(shù)的計數(shù)過程
LINQ(Language-Integrated Query)是C#和VB.NET中強(qiáng)大的查詢語言,它可以用來查詢集合、SQL數(shù)據(jù)庫、XML文檔等,在C#中,我們可以使用LINQ來簡化對字符串中特定單詞出現(xiàn)次數(shù)的計數(shù)過程,需要的朋友可以參考下2024-08-08macOS系統(tǒng)下Vscode的python配置教程
這篇文章主要介紹了macOS系統(tǒng)下Vscode的python配置教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04