公式字符串转换为公式或结果

发布时间:2020-10-21 01:42:13 作者:chcchb
来源:网络 阅读:475

方法一:DataColumn.Expression & DataTable.Compute方法(不支持函数)

DataColumn.Expression:

Dim objData As New DataTable
objData.Columns.Add("a", Type.GetType(Integer))
objData.Columns.Add("b", Type.GetType(Integer))
objData.Columns.Add("c", Type.GetType(Integer))
Dim objCol As DataColumn = _
    objData.Columns.Add("x", Type.GetType(Integer))
objCol.Expression = "a+b*c-2"
Dim objRow As DataRow = DataTable.NewRow()
objRow("a") = 2
objRow("b") = 3
objRow("c") = 4
objData.Rows.Add(objRow)
Console.WriteLine(objData.Rows(0)("x"))


DataTable.Compute:

MessageBox.Show((new DataTable()).Compute("1+2*3/4", "").ToString())


方法二:SQL的方式


方法三:解析

Imports System.Text.RegularExpressions
Public Class Evaluate
    Shared ReadOnly m_instance As New Evaluate()
    ''' <summary>
    ''' 构造函数
    ''' </summary>
    ''' <remarks></remarks>
    Shared Sub New()
    End Sub
    ''' <summary>
    ''' 获取实例
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared ReadOnly Property Instance() As Evaluate
        Get
            Return m_instance
        End Get
    End Property
    ' A number is a sequence of digits optionally followed by a dot and
    ' another sequence of digits. The number in parenthesis in order to
    ' define an unnamed group.
    Private Const Num As String = "(\-?\d+\.?\d*)"
    ' List of 1-operand functions.
    Private Const Func1 As String = "(exp|log|log10|abs|sqr|sqrt|sin|cos|tan|asin|acos|atan)"
    ' List of 2-operand functions.
    Private Const Func2 As String = "(atan2)"
    ' List of N-operand functions.
    Private Const FuncN As String = "(min|max)"
    ' List of predefined constants.
    Private Const Constants As String = "(e|pi)"
    Function Eval(ByVal expr As String) As Double
        ' Define one Regex object for each supported operation.
        ' They are outside the loop, so that they are compiled only once.
        ' Binary operations are defined as two numbers with a symbol between them
        ' optionally separated by spaces.
        Dim rePower As New Regex(Num & "\s*(\^)\s*" & Num)
        Dim reAddSub As New Regex(Num & "\s*([-+])\s*" & Num)
        Dim reMulDiv As New Regex(Num & "\s*([*/])\s*" & Num)
        ' These Regex objects resolve call to functions. (Case insensitivity.)
        Dim reFunc1 As New Regex(Func1 & "\(\s*" & Num & "\s*\)", _
            RegexOptions.IgnoreCase)
        Dim reFunc2 As New Regex(Func2 & "\(\s*" & Num & "\s*,\s*" & Num _
            & "\s*\)", RegexOptions.IgnoreCase)
        Dim reFuncN As New Regex(FuncN & "\((\s*" & Num & "\s*,)+\s*" & Num _
            & "\s*\)", RegexOptions.IgnoreCase)
        ' This Regex object drop a + when it follows an operator.
        Dim reSign1 As New Regex("([-+/*^])\s*\+")
        ' This Regex object converts a double minus into a plus.
        Dim reSign2 As New Regex("\-\s*\-")
        ' This Regex object drops parenthesis around a number.
        ' (must not be preceded by an alphanum char (it might be a function name)
        Dim rePar As New Regex("(?<![A-Za-z0-9])\(\s*([-+]?\d+.?\d*)\s*\)")
        ' A Regex object that tells that the entire expression is a number
        Dim reNum As New Regex("^\s*[-+]?\d+\.?\d*\s*$")
        ' The Regex object deals with constants. (Requires case insensitivity.)
        Dim reConst As New Regex("\s*" & Constants & "\s*", _
            RegexOptions.IgnoreCase)
        ' This resolves predefined constants. (Can be kept out of the loop.)
        expr = reConst.Replace(expr, AddressOf DoConstants)
        ' Loop until the entire expression becomes just a number.
        Do Until reNum.IsMatch(expr)
            Dim saveExpr As String = expr
            ' Perform all the math operations in the source string.
            ' starting with operands with higher operands.
            ' Note that we continue to perform each operation until there are
            ' no matches, because we must account for expressions like (12*34*56)
            ' Perform all power operations.
            Do While rePower.IsMatch(expr)
                expr = rePower.Replace(expr, AddressOf DoPower)
            Loop
            ' Perform all divisions and multiplications.
            Do While reMulDiv.IsMatch(expr)
                expr = reMulDiv.Replace(expr, AddressOf DoMulDiv)
            Loop
            ' Perform functions with variable numbers of arguments.
            Do While reFuncN.IsMatch(expr)
                expr = reFuncN.Replace(expr, AddressOf DoFuncN)
            Loop
            ' Perform functions with 2 arguments.
            Do While reFunc2.IsMatch(expr)
                expr = reFunc2.Replace(expr, AddressOf DoFunc2)
            Loop
            ' 1-operand functions must be processed last to deal correctly with
            ' expressions such as SIN(ATAN(1)) before we drop parenthesis
            ' pairs around numbers.
            Do While reFunc1.IsMatch(expr)
                expr = reFunc1.Replace(expr, AddressOf DoFunc1)
            Loop
            ' Discard + symbols (unary pluses)that follow another operator.
            expr = reSign1.Replace(expr, "$1")
            ' Simplify 2 consecutive minus signs into a plus sign.
            expr = reSign2.Replace(expr, "+")
            ' Perform all additions and subtractions.
            Do While reAddSub.IsMatch(expr)
                expr = reAddSub.Replace(expr, AddressOf DoAddSub)
            Loop
            ' attempt to discard parenthesis around numbers. We can do this
            expr = rePar.Replace(expr, "$1")
            ' if the expression didn't change, we have a syntax error.
            ' this serves to avoid endless loops
            If expr = saveExpr Then
                ' if it didn't work, exit with syntax error exception.
                Throw New Data.SyntaxErrorException()
                Return 0
            End If
        Loop
        ' Return the expression, which is now a number.
        Return CDbl(expr)
    End Function
    ' These functions evaluate the actual math operations.
    ' In all cases the Match object on entry has groups that identify
    ' the two operands and the operator.
    Function DoConstants(ByVal m As Match) As String
        Select Case m.Groups(1).Value.ToUpper
            Case "PI"
                Return Math.PI.ToString
            Case "E"
                Return Math.E.ToString
        End Select
        Return "0"
    End Function
    Function DoPower(ByVal m As Match) As String
        Dim n1 As Double = CDbl(m.Groups(1).Value)
        Dim n2 As Double = CDbl(m.Groups(3).Value)
        ' Group(2) is always the ^ character in this version.
        Return (n1 ^ n2).ToString
    End Function
    Function DoMulDiv(ByVal m As Match) As String
        Dim n1 As Double = CDbl(m.Groups(1).Value)
        Dim n2 As Double = CDbl(m.Groups(3).Value)
        Dim str As String = ""
        Select Case m.Groups(2).Value
            Case "/"
                str = (n1 / n2).ToString
            Case "*"
                str = (n1 * n2).ToString
        End Select
        Return str
    End Function
    Function DoAddSub(ByVal m As Match) As String
        Dim n1 As Double = CDbl(m.Groups(1).Value)
        Dim n2 As Double = CDbl(m.Groups(3).Value)
        Dim str As String = ""
        Select Case m.Groups(2).Value
            Case "+"
                str = (n1 + n2).ToString
            Case "-"
                str = (n1 - n2).ToString
        End Select
        Return str
    End Function
    ' These functions evaluate functions.
    Function DoFunc1(ByVal m As Match) As String
        ' function argument is 2nd group.
        Dim n1 As Double = CDbl(m.Groups(2).Value)
        Dim str As String = ""
        ' function name is 1st group.
        Select Case m.Groups(1).Value.ToUpper
            Case "EXP"
                str = Math.Exp(n1).ToString
            Case "LOG"
                str = Math.Log(n1).ToString
            Case "LOG10"
                str = Math.Log10(n1).ToString
            Case "ABS"
                str = Math.Abs(n1).ToString
            Case "SQR", "SQRT"
                str = Math.Sqrt(n1).ToString
            Case "SIN"
                str = Math.Sin(n1).ToString
            Case "COS"
                str = Math.Cos(n1).ToString
            Case "TAN"
                str = Math.Tan(n1).ToString
            Case "ASIN"
                str = Math.Asin(n1).ToString
            Case "ACOS"
                str = Math.Acos(n1).ToString
            Case "ATAN"
                str = Math.Atan(n1).ToString
        End Select
        Return str
    End Function
    Function DoFunc2(ByVal m As Match) As String
        ' function arguments are 2nd and 3rd group.
        Dim n1 As Double = CDbl(m.Groups(2).Value)
        Dim n2 As Double = CDbl(m.Groups(3).Value)
        Dim str As String = ""
        ' function name is 1st group.
        Select Case m.Groups(1).Value.ToUpper
            Case "ATAN2"
                str = Math.Atan2(n1, n2).ToString
        End Select
        Return str
    End Function
    Function DoFuncN(ByVal m As Match) As String
        ' function arguments are from group 2 onward.
        Dim args As New ArrayList()
        Dim i As Integer = 2
        ' Load all the arguments into the array.
        Do While m.Groups(i).Value <> ""
            ' Get the argument, replace any comma to space, and convert to double.
            args.Add(CDbl(m.Groups(i).Value.Replace(","c, " "c)))
            i += 1
        Loop
        Dim str As String = ""
        ' function name is 1st group.
        Select Case m.Groups(1).Value.ToUpper
            Case "MIN"
                args.Sort()
                str = args(0).ToString
            Case "MAX"
                args.Sort()
                str = args(args.Count - 1).ToString
        End Select
        Return str
    End Function
End Class


方法四:

http://www.codeproject.com/vb/net/expression_evaluator.asp


参考资料:http://blog.csdn.net/fangxinggood/article/details/5992661

推荐阅读:
  1. 子网划分公式及案例
  2. Machin formula /梅钦公式

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

字符串 符串

上一篇:oracle linux 4.8安装oracle 10g rac环境之database安装

下一篇:django 批量导入数据

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》