Excel VBA 逆引き集 | 正規表現の高度利用

Excel VBA
スポンサーリンク

ねらい:VBAで正規表現を「高度利用」し、複雑な文字処理を一瞬で片付ける

Excel VBAは標準の文字列関数(Left, Mid, InStrなど)でも処理できますが、複雑なパターン抽出や置換は正規表現(RegExpオブジェクト)を使うと圧倒的に速く、コードも短くなります。ここでは初心者でも理解できるように、基本の呼び出しから高度な利用(グループ化、否定先読み、複数条件抽出、置換テンプレート)まで例題を交えて解説します。

重要ポイントの深掘り

  • VBAで正規表現を使うには CreateObject("VBScript.RegExp") を生成します。参照設定不要のLate Bindingで安全。
  • パターンは「一度テストしてから本番に使う」習慣をつけると、誤抽出を防げます。
  • グループ化 () とキャプチャ、先読み (?=...) や否定先読み (?!...) を理解すると、複雑な条件を一行で表現できます。

基本形:RegExpオブジェクトの使い方

最小テンプレート

' ModRegexBase.bas
Option Explicit

Public Function RegexMatch(ByVal text As String, ByVal pattern As String) As Boolean
    Dim re As Object: Set re = CreateObject("VBScript.RegExp")
    re.Pattern = pattern
    re.IgnoreCase = True
    re.Global = False
    RegexMatch = re.Test(text)
End Function

Public Function RegexExtractAll(ByVal text As String, ByVal pattern As String) As Variant
    Dim re As Object: Set re = CreateObject("VBScript.RegExp")
    re.Pattern = pattern
    re.Global = True
    re.IgnoreCase = True
    Dim mc As Object: Set mc = re.Execute(text)
    Dim a() As String: ReDim a(1 To mc.Count)
    Dim i As Long
    For i = 1 To mc.Count
        a(i) = mc(i - 1).Value
    Next
    RegexExtractAll = a
End Function

Public Function RegexReplace(ByVal text As String, ByVal pattern As String, ByVal repl As String) As String
    Dim re As Object: Set re = CreateObject("VBScript.RegExp")
    re.Pattern = pattern
    re.Global = True
    re.IgnoreCase = True
    RegexReplace = re.Replace(text, repl)
End Function
VB

例題:メールアドレス抽出

Sub Demo_EmailExtract()
    Dim txt As String
    txt = "連絡先: user01@test.co.jp, backup: admin@domain.com"
    Dim arr As Variant: arr = RegexExtractAll(txt, "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}")
    Dim i As Long
    For i = LBound(arr) To UBound(arr)
        Debug.Print arr(i)
    Next
End Sub
VB

高度利用1:グループ化とキャプチャで部分抽出

グループを使って「日付の年・月・日」を分けて取る

Sub Demo_DateGroups()
    Dim txt As String: txt = "2025-12-16"
    Dim re As Object: Set re = CreateObject("VBScript.RegExp")
    re.Pattern = "(\d{4})-(\d{2})-(\d{2})"
    re.Global = False
    Dim mc As Object: Set mc = re.Execute(txt)
    If mc.Count > 0 Then
        Debug.Print "Year=" & mc(0).SubMatches(0)
        Debug.Print "Month=" & mc(0).SubMatches(1)
        Debug.Print "Day=" & mc(0).SubMatches(2)
    End If
End Sub
VB

重要ポイントの深掘り

  • SubMatches はグループごとの値を返します。複数の部分を一度に抽出できるため、文字列分割より効率的。
  • グループ番号は0から始まるので注意。

高度利用2:先読み・否定先読みで条件付き抽出

「httpで始まるが、httpsではないURL」を抽出

Sub Demo_NegativeLookahead()
    Dim txt As String: txt = "http://site.com https://secure.com"
    Dim arr As Variant: arr = RegexExtractAll(txt, "http(?!s)://[^\s]+")
    Dim i As Long
    For i = LBound(arr) To UBound(arr)
        Debug.Print arr(i)
    Next
End Sub
VB

重要ポイントの深掘り

  • (?!s) は「直後がsではない」ことを意味します。これでhttpのみ抽出可能。
  • 先読みは「文字を消費せず条件だけ確認」するため、柔軟なフィルタが可能です。

高度利用3:置換テンプレートで整形

電話番号を「国番号付き形式」に変換

Sub Demo_RegexReplacePhone()
    Dim txt As String: txt = "03-1234-5678"
    Dim res As String
    res = RegexReplace(txt, "(\d{2,4})-(\d{2,4})-(\d{4})", "+81-$1-$2-$3")
    Debug.Print res  ' +81-03-1234-5678
End Sub
VB

重要ポイントの深掘り

  • $1, $2, $3 はキャプチャグループの参照。置換文字列に埋め込むと整形が一瞬で済みます。
  • 電話番号や郵便番号など「パターンが決まっている文字列」の整形に最適です。

高度利用4:複数条件抽出と応用例

複数パターンをまとめて抽出(郵便番号と電話番号)

Sub Demo_MultiPattern()
    Dim txt As String
    txt = "郵便:123-4567 電話:03-1234-5678"
    Dim arr As Variant: arr = RegexExtractAll(txt, "(\d{3}-\d{4})|(\d{2,4}-\d{2,4}-\d{4})")
    Dim i As Long
    For i = LBound(arr) To UBound(arr)
        Debug.Print arr(i)
    Next
End Sub
VB

重要ポイントの深掘り

  • | は「OR条件」。複数のパターンを一度に走査できるため、別々に検索するより効率的。
  • 抽出結果は配列にまとめ、Excelシートへ一括書き込みすると大量データでも快適です。

実務での応用例

ログファイル解析

  • 日付+エラーメッセージを正規表現で抽出し、シートに一覧化。
  • 先読みで「ERRORの直後にコード番号がある行のみ」抽出するなど、条件を柔軟に設定可能。

データクレンジング

  • 不要な記号やタグを置換で削除。
  • 郵便番号や電話番号を正規化して、データベースに渡す前に整形。

まとめ:正規表現は「複雑な文字処理を一行で片付ける武器」

  • 基本は CreateObject("VBScript.RegExp") で生成し、Patternを設定。
  • グループ化で部分抽出、先読みで条件付き抽出、置換テンプレートで整形。
  • 大量データは配列にまとめて一括書き込み。
  • ログ解析やデータクレンジングに応用すると、Excel VBAの文字処理が一気に高度化します。

タイトルとURLをコピーしました