다음과 같은 유효한 수학 표현식이있는 문자열이있는 경우
String s = "1 + 2 * 7";
나를 위해 해당 표현식을 구문 분석하고 평가하고 결과를 반환하는 .NET에 내장 된 라이브러리 / 함수가 있습니까? 이 경우에 15.
답변
Microsoft 스크립트 제어 라이브러리 (COM)에 대한 참조를 추가하고 이와 같은 코드를 사용하여 식을 평가할 수 있습니다. (JScript에서도 작동합니다.)
Dim sc As New MSScriptControl.ScriptControl()
sc.Language = "VBScript"
Dim expression As String = "1 + 2 * 7"
Dim result As Double = sc.Eval(expression)
편집 -C # 버전.
MSScriptControl.ScriptControl sc = new MSScriptControl.ScriptControl();
sc.Language = "VBScript";
string expression = "1 + 2 * 7";
object result = sc.Eval(expression);
MessageBox.Show(result.ToString());
편집 -ScriptControl은 COM 개체입니다. 프로젝트의 “참조 추가”대화 상자에서 “COM”탭을 선택하고 “Microsoft Script Control 1.0″으로 스크롤 한 다음 확인을 선택합니다.
답변
이 유명하고 오래된 질문에 내장 된 DataTable.Compute
“트릭” 을 암시하는 대답이 없다는 것이 이상합니다 . 여기있어.
double result = Convert.ToDouble(new DataTable().Compute("1 + 2 * 7", null));
다음 산술 연산자는 표현식에서 지원됩니다.
+ (addition)
- (subtraction)
* (multiplication)
/ (division)
% (modulus)
더 많은 정보 : DataColumn.Expression
에서 표현 구문 .
답변
Silverlight에서 C #으로 개발하는 모든 사용자를 위해 Javascript 엔진을 호출하여 표현식을 평가할 수있는 매우 깔끔한 트릭이 있습니다.
double result = (double) HtmlPage.Window.Eval("15 + 35");
답변
당신은 본 적이 http://ncalc.codeplex.com를 ?
확장 가능하고 빠르므로 (예 : 자체 캐시가 있음) EvaluateFunction / EvaluateParameter 이벤트를 처리하여 런타임에 사용자 지정 함수와 변수를 제공 할 수 있습니다. 구문 분석 할 수있는 예제 표현식 :
Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");
e.Parameters["Pi2"] = new Expression("Pi * Pi");
e.Parameters["X"] = 10;
e.EvaluateParameter += delegate(string name, ParameterArgs args)
{
if (name == "Pi")
args.Result = 3.14;
};
Debug.Assert(117.07 == e.Evaluate());
또한 기본적으로 유니 코드 및 많은 데이터 유형을 처리합니다. 문법을 바꾸고 싶다면 녹용 파일이 함께 제공됩니다. 새로운 기능을로드하기 위해 MEF를 지원하는 포크도 있습니다.
답변
실제로 일종의 내장형이 있습니다. XPath 네임 스페이스를 사용할 수 있습니다! XPath 표기법으로 확인하려면 문자열을 다시 형식화해야합니다. 간단한 표현식을 처리하기 위해 다음과 같은 방법을 사용했습니다.
public static double Evaluate(string expression)
{
var xsltExpression =
string.Format("number({0})",
new Regex(@"([\+\-\*])").Replace(expression, " ${1} ")
.Replace("/", " div ")
.Replace("%", " mod "));
return (double)new XPathDocument
(new StringReader("<r/>"))
.CreateNavigator()
.Evaluate(xsltExpression);
}
답변
처음에는 muparser에 c # 래퍼를 사용 했습니다 . 이것은 매우 빠르다. 내가 아는 유일한 더 빠른 솔루션은 exprtk 입니다. 다른 솔루션을 찾고 있다면 벤치 마크를 확인할 수 있습니다 .
그러나 .Net의 경우 내장 지원을 사용하여 런타임에 코드를 컴파일 할 수 있습니다. 아이디어는 평가를위한 공식을 대체 할 수있는 임베디드 리소스와 같은 “템플릿”소스 파일을 갖는 것입니다. 그런 다음이 준비된 클래스 소스 코드를 컴파일러에 전달합니다.
기본 템플릿은 다음과 같습니다.
public class CSCodeEvaler
{
public double EvalCode()
{
return last = Convert.ToDouble(%formula%);
}
public double last = 0;
public const double pi = Math.PI;
public const double e = Math.E;
public double sin(double value) { return Math.Sin(value); }
public double cos(double value) { return Math.Cos(value); }
public double tan(double value) { return Math.Tan(value); }
...
식을 넣을 % formula %를 확인합니다.
컴파일하려면 CSharpCodeProvider 클래스를 사용하십시오. 여기에 완전한 소스를 넣고 싶지 않습니다. 그러나이 답변 이 도움 이 될 수 있습니다.
메모리 내 어셈블리를로드 한 후 클래스의 인스턴스를 만들고 EvalCode를 호출 할 수 있습니다.
답변
Roslyn을 사용할 수있는 또 다른 옵션 :
이를 위해 CodeAnalysis.CSharp.Scripting 라이브러리를 사용할 수 있습니다.
using Microsoft.CodeAnalysis.CSharp.Scripting;
using System;
namespace ExpressionParser
{
class Program
{
static void Main(string[] args)
{
//Demonstrate evaluating C# code
var result = CSharpScript.EvaluateAsync("System.DateTime.Now.AddDays(-1) > System.DateTime.Now").Result;
Console.WriteLine(result.ToString());
//Demonstrate evaluating simple expressions
var result2 = CSharpScript.EvaluateAsync(" 5 * 7").Result;
Console.WriteLine(result2);
Console.ReadKey();
}
}
}
너겟 패키지 :
<package id="Microsoft.CodeAnalysis.Analyzers" version="1.1.0" targetFramework="net461" />
<package id="Microsoft.CodeAnalysis.Common" version="1.1.1" targetFramework="net461" />
<package id="Microsoft.CodeAnalysis.CSharp" version="1.1.1" targetFramework="net461" />
<package id="Microsoft.CodeAnalysis.CSharp.Scripting" version="1.1.1" targetFramework="net461" />
<package id="Microsoft.CodeAnalysis.Scripting" version="1.1.1" targetFramework="net461" />
<package id="Microsoft.CodeAnalysis.Scripting.Common" version="1.1.1" targetFramework="net461" />