Выполнение математики в vb.net как Eval в javascript

Есть ли способ проанализировать строку в vb.net (например, встроенные методы), которая может выполнять математику, такую ​​как Eval? Например, 3+ (7 / 3.5) в качестве строки вернет 2.

Я не прошу вас закодировать это для меня, я просто хочу знать, есть ли встроенный способ сделать это, если нет, я сам его закодирую.

Я могу утверждать, что он не сможет самостоятельно разбирать такие вещи, как Sin (90), и я понимаю, что его нужно заменить Math.Sin (90).

Если есть встроенный метод, как вы его используете?

Для ограниченного (т. Е. Простого) математического выражения есть ярлык с использованием метода DataTable.Compute . Очевидно, что это не является надежным (ограниченная функциональность) и кажется хакерским для неправильного использования DataTable для этой цели, но я решил, что добавлю к текущим ответам.

Пример:

var result = new DataTable().Compute("3+(7/3.5)", null); // 5 

«Грех (90)» не будет работать с этим подходом. См. Страницу свойств DataColumn.Expression для списка поддерживаемых функций, в частности в разделе «Агрегаты».

Использование пространства имен System.CodeDom является опцией.

Некоторые полезные ссылки:

  • Калькулятор CodeDom
  • Оценка математических выражений с помощью CodeDom
  • Связанный вопрос SO: Есть ли в математике оценщик строк?

EDIT: чтобы ответить на ваш комментарий, рассмотрим подход, демонстрирующий замену тригонометрических функций их эквивалентными методами classа Math.

C #

 string expression = "(Sin(0) + Cos(0)+Tan(0)) * 10"; string updatedExpression = Regex.Replace(expression, @"(?Sin|Cos|Tan)\((?.*?)\)", match => match.Groups["func"].Value == "Sin" ? Math.Sin(Int32.Parse(match.Groups["arg"].Value)).ToString() : match.Groups["func"].Value == "Cos" ? Math.Cos(Int32.Parse(match.Groups["arg"].Value)).ToString() : Math.Tan(Int32.Parse(match.Groups["arg"].Value)).ToString() ); var result = new DataTable().Compute(updatedExpression, null); // 10 

VB.NET

 Dim expression As String = "(Sin(0) + Cos(0)+Tan(0)) * 10" Dim updatedExpression As String = Regex.Replace(expression, "(?Sin|Cos|Tan)\((?.*?)\)", Function(match As Match) _ If(match.Groups("func").Value = "Sin", Math.Sin(Int32.Parse(match.Groups("arg").Value)).ToString(), _ If(match.Groups("func").Value = "Cos", Math.Cos(Int32.Parse(match.Groups("arg").Value)).ToString(), _ Math.Tan(Int32.Parse(match.Groups("arg").Value)).ToString())) _ ) Dim result = New DataTable().Compute(updatedExpression, Nothing) 

Обратите внимание, однако, что вам нужно знать содержимое группы «arg». Я знаю, что они ints, поэтому я использовал Int32.Parse на них. Если они представляют собой комбинацию предметов, тогда этот простой подход не будет работать. Я подозреваю, что вам постоянно нужно будет помогать решению, если оно становится слишком сложным с более неподдерживаемыми вызовами функций, и в этом случае подход CodeDom или другие могут быть более подходящими.

Вот способ оценить выражение, которое я не видел нигде: используйте элемент управления WebBrowser и JavaScript eval() :

 Option Strict On Imports System.Security.Permissions  _  Public Class Form1 Dim browser As New WebBrowser Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load browser.ObjectForScripting = Me 'browser.ScriptErrorsSuppressed = True browser.DocumentText = "" End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim result = browser.Document.InvokeScript("evalIt", New String() {"3+4*5"}) If result IsNot Nothing Then MessageBox.Show(result.ToString()) '23 End If End Sub End Class 

Эта статья CodeProject может сделать трюк:

Оценщик выражений, написанный на VB.NET
http://www.codeproject.com/KB/vb/expression_evaluator.aspx

Существует также следующее:
http://www.dotnetspider.com/resources/2518-mathematical-expression-expression-evaluate-VB.aspx

Я не знаю о встроенном VB.net, но мы делаем это так, связываясь во время выполнения IronPython и передавая ему выражения. Это путь быстрее, чем использование рефлексии.

Один из способов – использовать пространство имен CodeDom для его компиляции и выполнить его с помощью отражения. Может быть, это не исполнитель, я не знаю.

Немного поздно, но вот именно то, что вы хотели (убедитесь, что вы разбираете ввод, чтобы убедиться, что в нем нет выражения типа «что-то + vbcrlf + exec» c: “‘):

Применение:

 MessageBox.Show(COR.Tools.EvalProvider.Eval("return 8-3*2").ToString()) 

Класс:

 'Imports Microsoft.VisualBasic Imports System Namespace COR.Tools Public Class EvalProvider Public Shared Function Eval(ByVal vbCode As String) As Object Dim c As VBCodeProvider = New VBCodeProvider Dim icc As System.CodeDom.Compiler.ICodeCompiler = c.CreateCompiler() Dim cp As System.CodeDom.Compiler.CompilerParameters = New System.CodeDom.Compiler.CompilerParameters cp.ReferencedAssemblies.Add("System.dll") cp.ReferencedAssemblies.Add("System.xml.dll") cp.ReferencedAssemblies.Add("System.data.dll") ' Sample code for adding your own referenced assemblies 'cp.ReferencedAssemblies.Add("c:\yourProjectDir\bin\YourBaseClass.dll") 'cp.ReferencedAssemblies.Add("YourBaseclass.dll") cp.CompilerOptions = "/t:library" cp.GenerateInMemory = True Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder("") sb.Append("Imports System" & vbCrLf) sb.Append("Imports System.Xml" & vbCrLf) sb.Append("Imports System.Data" & vbCrLf) sb.Append("Imports System.Data.SqlClient" & vbCrLf) sb.Append("Imports Microsoft.VisualBasic" & vbCrLf) sb.Append("Namespace MyEvalNamespace " & vbCrLf) sb.Append("Class MyEvalClass " & vbCrLf) sb.Append("public function EvalCode() as Object " & vbCrLf) 'sb.Append("YourNamespace.YourBaseClass thisObject = New YourNamespace.YourBaseClass()") sb.Append(vbCode & vbCrLf) sb.Append("End Function " & vbCrLf) sb.Append("End Class " & vbCrLf) sb.Append("End Namespace" & vbCrLf) Debug.WriteLine(sb.ToString()) ' look at this to debug your eval string Dim cr As System.CodeDom.Compiler.CompilerResults = icc.CompileAssemblyFromSource(cp, sb.ToString()) Dim a As System.Reflection.Assembly = cr.CompiledAssembly Dim o As Object Dim mi As System.Reflection.MethodInfo o = a.CreateInstance("MyEvalNamespace.MyEvalClass") Dim t As Type = o.GetType() mi = t.GetMethod("EvalCode") Dim s As Object s = mi.Invoke(o, Nothing) Return s End Function End Class ' EvalProvider End Namespace 
  • Разница между Lookup () и словарем (из списка ())
  • Ограничения управления Webbrowser
  • Веб-страница работает в IE, Chrome и Firefox, но не при использовании элемента управления .NET WebBrowser
  • Как я могу обработать обработчик одного события ALL Button.Click?
  • Эквивалент MoveNext в VB.NET
  • Маркировка classа Static в VB.NET
  • Правильный способ размещения объекта Excel com с помощью VB.NET?
  • VB.NET - IsNothing против нет ничего
  • Использование связанных данных, хранящихся в двумерном массиве
  • обработка данных dbnull в vb.net
  • Можно ли записать на консоль цвет в .NET?
  • Давайте будем гением компьютера.