文字列数式評価(2)~かっこの処理

ではまず、かっこの中を抜き出す処理

'   機 能  :   かっこ内にある文字列
'   書 式  :   XInPTxt(s, [t])
'               XInPTxt s, [t]
'   返り値  :   最初のあらわれる開きかっこと
'               それに対応する閉じかっこの間の文字列
'   引 数  :   s   -   文字列
'               t   -   かっこ間の文字列を格納する変数
'   説 明  :   かっこの対応が正しくない場合はエラーを返す

Public Function XInPtxt(ByVal s, Optional t) As String

    Dim i               As Long         '   繰り返し変数
    Dim c               As String       '   調べる文字
    Dim d               As Long         '   かっこの深さ
    Dim lp              As Long         '   開きかっこ位置
    Dim rp              As Long         '   閉じかっこ位置

    For i = 1 To Len(s)
        c = Mid(s, i, 1)
        Select Case c
            Case "("
                d = d + 1
                '   d = 1 ならば、最初の開きかっこ
                If d = 1 Then lp = i
            Case ")"
                d = d - 1
                '   d = 0 ならば、対応する閉じかっこ
                If d = 0 Then
                    rp = i
                    Exit For
                End If
                '   d < 0 ならば、対応する開きかっこが存在しない
                If d < 0 Then Exit For
        End Select
    Next
   
    '   開き/閉じかっこが正しく対応してないときエラーを返す
    If d <> 0 Then
        Err.Raise 9001, , "かっこが正しく対応していません"
        Exit Function
    End If

    t = Mid(s, lp + 1, rp - lp - 1)
   
    XInPtxt = t

End Function

特に難しいことをしてるわけではなく、
左から1文字ずつ読み込んで、開きかっこの位置と
かっこの深さに注意しながら閉じかっこを探すだけの処理。
途中のエラー処理は適当にこしらえたものなので、
無視しても構わない。
なんなら、必要なだけかっこを補って再処理させる方法もありかと。

数式評価関数をXEval、数式文字列をs、かっこ内文字列をs_とすると
再帰させる方法は(形式的に書くと)次のようになる。

XEval(s) = XEval(Replace(s, "(" & s_ & ")", XEval(s_))

※ あとから気づいたことだが、かっこに入った同じ文字列はこれで一気に片付く。

これをかっこがなくなるまでDo~Loopで繰り返せばいい。

コメント

このブログの人気の投稿

文字列数式評価(5)~各項の和

文字列数式評価(3)~符号処理

文字列数式評価(1)