正規表現:サブマッチ取得


例題

カラム位置が不定な特定の情報をレコードから取り出す際に正規表現を使って、
サブマッチを取得すると比較的楽に取り出せます。
例えば、次のようなVBAプログラムの解析を行っているとして、各行を見てCall文がある場合に、
そのときに呼び出しているプロシージャ名を取得したいとします。


Sub Test()

  Dim FlgEnd As Boolean


  Call InitProcess

  Do While FlgEnd = False
     Call MainProcess(FlgEnd)
  Loop

  Call FinalProcess

End Sub

解答

Option Explicit
Option Base 1

Sub RESM1()

  Dim InputSrc(15) As String
  Dim I As Long
  Dim RE As Object
  Dim MATCHES As Object
  

  InputSrc(1) = ""
  InputSrc(2) = "Sub Test()"
  InputSrc(3) = ""
  InputSrc(4) = "  Dim FlgEnd As Boolean"
  InputSrc(5) = ""
  InputSrc(6) = ""
  InputSrc(7) = "  Call InitProcess"
  InputSrc(8) = ""
  InputSrc(9) = "  Do While FlgEnd = False"
  InputSrc(10) = "     Call MainProcess(FlgEnd)"
  InputSrc(11) = "  Loop"
  InputSrc(12) = ""
  InputSrc(13) = "  Call FinalProcess"
  InputSrc(14) = ""
  InputSrc(15) = "End Sub"


  Set RE = CreateObject("VBScript.RegExp")
  With RE
     .Pattern = "^ *?Call +?([^ \(]+).*?$"                           '…@
     .IgnoreCase = True
     .Global = False
  End With
  
  For I = 1 To UBound(InputSrc)
     If InStr(InputSrc(I), "Call ") > 0 Then
        If RE.Test(InputSrc(I)) = True Then
           Set MATCHES = RE.Execute(InputSrc(I))
           Debug.Print I & "行目:" & MATCHES(0).Submatches(0)       '…A
           Set MATCHES = Nothing
        End If
     End If
  Next I

  Set RE = Nothing

End Sub

MATCHESコレクションを使った方法。
@:この方法の場合、今回はそうしているが、正規表現で先頭^と末尾$で行全体をマッチさせる必要はない。
A:MATCHES(0)は行全体で、Submatches(0)はプロシージャ名になる。

別解

Option Explicit
Option Base 1

Sub RESM2()

  Dim InputSrc(15) As String
  Dim I As Long
  Dim RE As Object
  Dim ProcName As String
  

  InputSrc(1) = ""
  InputSrc(2) = "Sub Test()"
  InputSrc(3) = ""
  InputSrc(4) = "  Dim FlgEnd As Boolean"
  InputSrc(5) = ""
  InputSrc(6) = ""
  InputSrc(7) = "  Call InitProcess"
  InputSrc(8) = ""
  InputSrc(9) = "  Do While FlgEnd = False"
  InputSrc(10) = "     Call MainProcess(FlgEnd)"
  InputSrc(11) = "  Loop"
  InputSrc(12) = ""
  InputSrc(13) = "  Call FinalProcess"
  InputSrc(14) = ""
  InputSrc(15) = "End Sub"


  Set RE = CreateObject("VBScript.RegExp")
  With RE
     .Pattern = "^ *?Call +?([^ \(]+).*?$"                           '…@
     .IgnoreCase = True
     .Global = False
  End With
  
  For I = 1 To UBound(InputSrc)
     If InStr(InputSrc(I), "Call ") > 0 Then
        If RE.Test(InputSrc(I)) = True Then
           ProcName = RE.Replace(InputSrc(I), "$1")                  '…A
           Debug.Print I & "行目:" & ProcName
        End If
     End If
  Next I

  Set RE = Nothing

End Sub

サブマッチを置換で取得する方法
@:この方法の場合、正規表現で先頭^と末尾$で行全体をマッチさせる必要がある。
  そうしないと置換後に前後にごみが残る。
A:マッチした行全体をサブマッチで置換することでサブマッチの値を取得している。

イミディエイトウィンドウ

どちらも次のように出力されます。


7行目:InitProcess
10行目:MainProcess
13行目:FinalProcess


Excel VBA講座に戻ります

トップに戻ります


お探しの情報は見つかりましたか?
まだの方はこちらをどうぞ。
Google

PageTop