VBA에서 정규식 매칭에 의한 부분 문자열 추출

19518 단어 ExcelVBA

개요



하고 싶은 일



VBA에서 정규식 일치를 수행하여 부분 일치 문자열을 추출합니다.

본문



포인트라고 할까는 멈춘 부분


  • regex.Execute() 반환 값은 Matches 컬렉션입니다.
  • Matches에 여러 요소를 입력하려면 Global 속성을 true로 설정해야 합니다.
  • Matches의 요소인 Match는\1,\2,,,가 아니라 regex.pattern 전체에 일치하는 것이 들어 있다.
  • Match는 SubMatches를 가지고 있으며 여기에는\1,\2,,,의 하위 문자열이 들어 있습니다

  • 코드 샘플



    모두 표준 모듈에 붙이면 그대로 움직일 것입니다.

    간단한 정규 표현식으로 여러 일치하는 사람


    Option Explicit
    
    Sub regexSample1()
    
        Dim regex As Object
        Set regex = CreateObject("VBScript.RegExp")
        regex.pattern = "([0-9]{4}/[0-9]{2}/[0-9]{2}) (.+)"
        regex.Global = True ' matchesを複数取得したい場合には必要
    
        ' マッチ対象文字列
        Dim s As String
        s = "2019/01/03 晴れ" & vbLf & "2019/02/04 雨" & vbLf & "2019/03/05 かみなり"
    
        ' マッチ実施
        Dim matches As Variant
        Set matches = regex.Execute(s)
    
        ' 結果をログ出力
        Dim match As Variant
        For Each match In matches
            Debug.Print "日付:" & match.submatches(0) & ", 天気:" & match.submatches(1)
        Next match
        Debug.Print
    End Sub
    

    결과 (이미디에이트 창으로 출력)
    日付:2019/01/03, 天気:晴れ
    日付:2019/02/04, 天気:雨
    日付:2019/03/05, 天気:かみなり
    

    이스케이프와 같은 복잡한 사람


    Option Explicit
    
    Sub regexSample2()
    
        ' サンプル用のブックとシートを作成
        Workbooks.Add
        Dim wb As Workbook, ws As Worksheet
        Set wb = ActiveWorkbook
        Set ws = ActiveSheet
        With ws.Cells
            .Font.Name = "MS ゴシック"
            .Font.Size = 9
            .NumberFormatLocal = "@"
        End With
    
        ' サンプル用シートにログを出力
        Call setLog(ws)
    
        ' 正規表現オブジェクトの作成
        Dim regex As Object
        Set regex = CreateObject("VBScript.RegExp")
        Dim p As String
        p = ""
        p = p & "^" ' 行開始
        p = p & "([^ ]+)" ' \1:IPaddress(最初の空白まで)
        p = p & "[^\]]+" ' タイムスタンプの手前まで。"]"には正規表現としてのエスケープ\が必要
        p = p & "\[" ' "["には正規表現としてのエスケープ\が必要
        p = p & "([0-9]{1,2})/([a-zA-Z]+)/([0-9]{4}):([0-9]{2}:[0-9]{2}:[0-9]{2}) *" ' \2:日 \3:月 \4:年 \5:時分秒
        p = p & "([^]]+)\] *" '  \6\タイムゾーン
        p = p & """([^ ]+) *" ' \7:メソッド名
        p = p & "([^ ]*) " '\8: アクセスパス
        p = p & "([^""]*)"" *" ' \9:HTTPバージョン (「"」にはVBA文字列としてのエスケープ「"」が必要)
        p = p & "([0-9]+) *" ' \10:ステータスコード
        p = p & "[0-9]+" ' \11:プロセス番号
        p = p & "$" ' 行おわり
        regex.Pattern = p
    
        ' 出力ログ1行(A列のセル1つ)ごとに処理する
        Dim wrIn As Range
        Set wrIn = ws.Range("A2")
        Do While wrIn.Value <> ""
    
            Dim matches As Variant ' デバッグするとIMatchCollection2型とかなんだけど、定義の仕方がわからないのでvariantでごまかす
            Set matches = regex.Execute(wrIn.Value) ' 正規表現マッチングの実行
    
            If matches.Count = 1 Then ' ログ1行に対して「行頭~行末」でマッチングしているので、結果countは0か1
                Dim match As Variant ' デバッグするとIMatch2型とかなんだけど、定義の仕方がわからないのでvariantでごまかす
                Set match = matches(0)
                Dim idxMatch As Long
                Dim wrOut As Range
                Set wrOut = wrIn.Offset(0, 1)
                ' マッチ結果の\1,\2,,,はsubmatchesに格納されている
                For idxMatch = 0 To match.submatches.Count - 1
                    wrOut.Value = match.submatches(idxMatch)
                    Set wrOut = wrOut.Offset(0, 1)
                Next idxMatch
            Else
                wrIn.Offset(0, 1).Value = "not matched."
            End If
    
            Set wrIn = wrIn.Offset(1, 0)
        Loop
    
        ' 出力結果を整形
        ws.Range(ws.Cells(1, 1), ws.Cells(1, ws.Cells.SpecialCells(xlCellTypeLastCell).Column)).Value = Array("log", "IP", "day", "month", "year", "time", "timezone", "method", "access path", "http ver", "status", "process")
        ws.Range("B2").Select
        ActiveWindow.FreezePanes = True
        ws.Cells(1, 1).EntireColumn.ColumnWidth = 3
        ws.Range(ws.Cells(1, 2), ws.Cells(1, ws.Cells.SpecialCells(xlCellTypeLastCell).Column)).EntireColumn.AutoFit
    
        MsgBox "done"
    End Sub
    
    
    ' ワークシートにサンプルログを出力する
    ' ログはこちらから拝借
    ' https://httpd.apache.org/docs/2.2/ja/logs.html#accesslog
    Private Function setLog(ws As Worksheet)
        Dim log As Variant
    
        log = Array( _
            "127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] ""GET /apache_pb.gif HTTP/1.0"" 200 2326" _
            , "127.0.0.1 - frank [1/Oct/2000:13:55:36 -0700] ""POST /apache_pb.gif?attr=value HTTP/1.0"" 200 2326" _
            )
        Dim wr As Range
        Set wr = ws.Range("A2") ' ログ出力開始セル
        Dim i As Long
        For i = LBound(log) To UBound(log)
            wr.Value = log(i)
            Set wr = wr.Offset(1, 0)
        Next i
    End Function
    

    결과 (새로운 Excel 통합 문서로 출력)


    참고


  • Execute 메서드 (VBScript) - MSDN - Microsoft
    - htps : // / cs. 미 c 로소 ft. 코 m/쟈-jp/p레ゔぃおう sーゔぇr 시온 s/우뎅도ws/sc리p찜g/ㄷc392389(v=msd응.10)
  • SubMatches 컬렉션
    - htps : // / cs. 미 c 로소 ft. 이 m/쟈-jp/p레ゔぃおう sーゔぇr시온 s/우뎅도ws/sc리p찜g/ㄷc392216%28v%3dmsd응. 10% 29
  • 좋은 웹페이지 즐겨찾기