正在计算字符串“3*(4+2)” 产量整数 18
.NET 框架是否有一个函数可以计算字符串中包含的数字表达式并返回结果? Fe:
string mystring = "3*(2+4)";
int result = EvaluateExpression(mystring);
Console.Writeln(result); // Outputs 18
是否有一个标准框架函数可以替代我的 EvaluateExpression
方法?
Is there a function the .NET framework that can evaluate a numeric expression contained in a string and return the result? F.e.:
string mystring = "3*(2+4)";
int result = EvaluateExpression(mystring);
Console.Writeln(result); // Outputs 18
Is there a standard framework function that you can replace my EvaluateExpression
method with?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
其工作原理说明:
首先,我们在
var loDataTable = new DataTable();
部分创建一个表,就像在数据库引擎中一样(例如 MS SQL)。然后是一个带有一些特定参数的列(
var loDataColumn = new DataColumn("Eval", typeof (double), expression);
)。"Eval"
参数是列的名称(ColumnName 属性)。typeof (double)
是要存储在列中的数据类型,相当于 putSystem.Type.GetType("System.Double");
。表达式
是Evaluate
方法接收的字符串,并存储在列的属性Expression
中。 这个属性有一个真正特定的目的(显而易见),即放置在列上的每一行都将用“表达式”填充,并且它实际上接受可以放入 SQL 查询中的任何内容。 请参阅 http:// msdn.microsoft.com/en-us/library/system.data.datacolumn.expression(v=vs.100).aspx 了解可以在 Expression 属性中放入哪些内容以及如何计算它。然后,
loDataTable.Columns.Add(loDataColumn);
将列loDataColumn
添加到loDataTable
表中。然后,通过
loDataTable.Rows.Add(0);
向表中添加一行,其中包含带有 Expression 属性的个性化列。 当我们添加这一行时,表loDataTable
的“Eval”列的单元格会自动填充其“Expression”属性,并且,如果它有运算符和 SQL 查询等,则会对其进行评估并进行计算然后存储到单元格中,所以,这里发生了“魔术”,带有运算符的字符串被计算并存储到单元格中...最后,只需返回存储到第 0 行“Eval”列的单元格中的值(它是索引,从零开始计数),并使用
return (double) (loDataTable.Rows[0]["Eval"]);
转换为双精度值。这就是全部...工作完成!
这里有一个更容易理解的代码,它的作用是相同的......它不在方法内部,并且也进行了解释。
首先,使用
DataTable MyTable = new DataTable();
创建表,然后使用
DataColumn MyColumn = new DataColumn();
创建列,接下来,我们为该列命名。 这样我们就可以在它存储到表中时搜索它的内容。 通过
MyColumn.ColumnName = "MyColumn";
然后是表达式,这里我们可以放置一个字符串类型的变量,在本例中有一个预定义的字符串“5+5/5”,其结果是6.
要存储到列的数据类型
MyColumn.DataType = typeof(double);
将列添加到表中...
MyTable.Columns.Add(MyColumn);< /code>
创建一行要插入到表中,这会复制表结构
DataRow MyRow = MyTable.NewRow();
使用
MyTable.Rows.Add( 将行添加到表中MyRow);
并返回表
MyTable
的MyColumn
列的第 0 行单元格的值,其中return (double)(MyTable. Rows[0]["MyColumn"]);
课程完成!!!
Explanation of how it works:
First, we make a table in the part
var loDataTable = new DataTable();
, just like in a Data Base Engine (MS SQL for example).Then, a column, with some specific parameters (
var loDataColumn = new DataColumn("Eval", typeof (double), expression);
).The
"Eval"
parameter is the name of the column (ColumnName attribute).typeof (double)
is the type of data to be stored in the column, which is equal to putSystem.Type.GetType("System.Double");
instead.expression
is the string that theEvaluate
method receives, and is stored in the attributeExpression
of the column. This attribute is for a really specific purpose (obvious), which is that every row that's put on the column will be fullfilled with the "Expression", and it accepts practically wathever can be put in a SQL Query. Refer to http://msdn.microsoft.com/en-us/library/system.data.datacolumn.expression(v=vs.100).aspx to know what can be put in the Expression attribute, and how it's evaluated.Then,
loDataTable.Columns.Add(loDataColumn);
adds the columnloDataColumn
to theloDataTable
table.Then, a row is added to the table with a personalized column with a Expression attribute, done via
loDataTable.Rows.Add(0);
. When we add this row, the cell of the column "Eval" of the tableloDataTable
is fullfilled automatically with its "Expression" attribute, and, if it has operators and SQL Queries, etc, it's evaluated and then stored to the cell, so, here happens the "magic", the string with operators is evaluated and stored to a cell...Finally, just return the value stored to the cell of the column "Eval" in row 0 (it's an index, starts counting from zero), and making a conversion to a double with
return (double) (loDataTable.Rows[0]["Eval"]);
.And that's all... job done!
And here a code eaiser to understand, which does the same... It's not inside a method, and it's explained too.
First, create the table with
DataTable MyTable = new DataTable();
Then, a column with
DataColumn MyColumn = new DataColumn();
Next, we put a name to the column. This so we can search into it's contents when it's stored to the table. Done via
MyColumn.ColumnName = "MyColumn";
Then, the Expression, here we can put a variable of type string, in this case there's a predefined string "5+5/5", which result is 6.
The type of data to be stored to the column
MyColumn.DataType = typeof(double);
Add the column to the table...
MyTable.Columns.Add(MyColumn);
Make a row to be inserted to the table, which copies the table structure
DataRow MyRow = MyTable.NewRow();
Add the row to the table with
MyTable.Rows.Add(MyRow);
And return the value of the cell in row 0 of the column
MyColumn
of the tableMyTable
withreturn (double)(MyTable.Rows[0]["MyColumn"]);
Lesson done!!!
这是从右到左执行,因此需要使用适当的括号来执行表达式
This is right to left execution, so need to use proper parathesis to execute expression
您可以相当轻松地通过 CSharpCodeProvider 运行它,并使用合适的绒毛包装它(基本上是类型和方法)。 同样,您可以使用 VB 等 - 或 JavaScript,正如另一个答案所建议的那样。 目前我不知道框架中还内置了任何其他内容。
我预计 .NET 4.0 及其对动态语言的支持很可能在这方面具有更好的功能。
You could fairly easily run this through the CSharpCodeProvider with suitable fluff wrapping it (a type and a method, basically). Likewise you could go through VB etc - or JavaScript, as another answer has suggested. I don't know of anything else built into the framework at this point.
I'd expect that .NET 4.0 with its support for dynamic languages may well have better capabilities on this front.
我最近需要为一个项目执行此操作,最终使用 IronPython 来做到这一点。 您可以声明引擎的实例,然后传递任何有效的 python 表达式并获取结果。 如果您只是做简单的数学表达式,那么就足够了。 我的代码最终看起来类似于:
您可能不想为每个表达式创建引擎。 您还需要对 IronPython.dll 的引用
I recently needed to do this for a project and I ended up using IronPython to do it. You can declare an instance of the engine, and then pass any valid python expression and get the result. If you're just doing simple math expressions, then it would suffice. My code ended up looking similar to:
You'd probably not want to create the engine for each expression. You also need a reference to IronPython.dll
编辑:意识到我真的应该将加法和减法分开,以使其更符合 BODMAS 要求。
非常感谢 Rajesh Jinaga 基于堆栈的方法。 我发现它对我的需求非常有用。 以下代码是对 Rajesh 方法的轻微修改,该方法首先处理除法,然后处理乘法,最后处理加法和减法。 它还允许在表达式中使用布尔值,其中 true 被视为 1, false 被视为 0。允许在表达式中使用布尔逻辑。
我知道可能有一种更干净的方法来做到这一点,我想我只是分享一下它的第一眼,以防有人发现它有用。
EDIT: Realised i should really bring the addition and subtraction out seperately aswell to make it a little bit more BODMAS compliant.
Big thanks to Rajesh Jinaga for his Stack based approach. I found it really useful for my needs. The following code is a slight modification of Rajesh's method, which processes divisions first, then multiplications, then finishes up with addition and subtraction. It will also allow the use of booleans in the expressions, where true is treated as 1 and false 0. allowing the use of boolean logic in expressions.
I know there is likely to be a cleaner way of doing it, thought id just share the first look at it in case anyone finds it usefull.
非常感谢拉梅什。 我使用他的简单代码的一个版本从数据库中提取一个字符串,并用它在我的代码中执行布尔运算。
x 是一个数字,如 1500 或 2100 等。
函数将是一个存储的评估,例如 x > 1400且x<1 1600
Many thanks to Ramesh. I used a version of his simple code to pull a string out a database and use it to do boolean operations in my code.
x is a number like 1500 or 2100 or whatever.
function would be a stored evaluation like x > 1400 and x < 1600
那没有。 您将需要使用一些外部库,或编写自己的解析器。 如果您有时间这样做,我建议您编写自己的解析器,因为这是一个非常有趣的项目。 否则,您将需要使用类似 bcParser 的东西。
There is not. You will need to use some external library, or write your own parser. If you have the time to do so, I suggest to write your own parser as it is a quite interesting project. Otherwise you will need to use something like bcParser.
简短回答:我不这么认为。 据我所知,C# .Net 已编译(为字节码),并且无法在运行时评估字符串。 然而,JScript .Net 可以; 但我仍然建议您自己编写一个解析器和基于堆栈的求值器。
Short answer: I don't think so. C# .Net is compiled (to bytecode) and can't evaluate strings at runtime, as far as I know. JScript .Net can, however; but I would still advise you to code a parser and stack-based evaluator yourself.
如果您想计算字符串表达式,请使用以下代码片段。
If you want to evaluate a string expression use the below code snippet.
使用编译器执行此操作意味着内存泄漏,因为生成的程序集已加载但从未释放。 它的性能也低于使用真正的表达式解释器。 为此,您可以使用 Ncalc,这是一个仅用于此目的的开源框架。 如果已经包含的变量和自定义函数还不够,您还可以定义自己的变量和自定义函数。
例子:
Using the compiler to do implies memory leaks as the generated assemblies are loaded and never released. It's also less performant than using a real expression interpreter. For this purpose you can use Ncalc which is an open-source framework with this solely intent. You can also define your own variables and custom functions if the ones already included aren't enough.
Example:
尝试这个:
Try this:
您可以查看“XpathNavigator.Evaluate”,我用它来处理我的 GridView 的数学表达式,它对我来说效果很好。
这是我的程序使用的代码:
You could look at "XpathNavigator.Evaluate" I have used this to process mathematical expressions for my GridView and it works fine for me.
Here is the code I used for my program:
这是一个使用堆栈的简单表达式求值器
This is a simple Expression Evaluator using Stacks