VBAには標準の正規表現がないと知った時は驚きましたが、VBScript.RegExpを参照設定なしで使う方法を見つけてからは手放せないツールになりました。実際に業務で使ったパターン例を中心に紹介します。

RegExp オブジェクトの生成

VBA正規表現フロー図

図1: RegExpオブジェクトのプロパティとメソッド

VBA — RegExp 生成(レイトバインディング)
Option Explicit

Function CreateRegExp(ByVal pattern As String, _
                      Optional ByVal ignoreCase As Boolean = False, _
                      Optional ByVal globalMatch As Boolean = True) As Object
    Dim re As Object
    Set re = CreateObject("VBScript.RegExp")
    re.Pattern    = pattern
    re.IgnoreCase = ignoreCase
    re.Global     = globalMatch
    Set CreateRegExp = re
End Function

プロパティ一覧

プロパティ内容
PatternString正規表現パターン文字列
IgnoreCaseBooleanTrue で大文字小文字を区別しない
GlobalBooleanTrue で全マッチを検索(False は最初の1件のみ)
MultiLineBooleanTrue で ^ / $ が行頭・行末にマッチ

Test — 一致確認

VBA — Test
Sub TestExample()
    Dim re As Object
    Set re = CreateRegExp("^\d{3}-\d{4}$")  ' 郵便番号パターン

    Debug.Print re.Test("123-4567")   ' → True
    Debug.Print re.Test("1234567")    ' → False
    Debug.Print re.Test("abc-1234")   ' → False

    Set re = Nothing
End Sub

Execute — マッチ結果の取得

VBA — Execute でメールアドレスを抽出
Sub ExecuteExample()
    Dim re      As Object
    Dim matches As Object
    Dim m       As Object

    Set re = CreateRegExp("[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}")

    Dim text As String
    text = "連絡先: foo@example.com または bar@test.co.jp"

    Set matches = re.Execute(text)

    For Each m In matches
        Debug.Print m.Value   ' → foo@example.com / bar@test.co.jp
    Next m

    Set matches = Nothing
    Set re = Nothing
End Sub

Replace — 置換

VBA — Replace で数字をマスク
Sub ReplaceExample()
    Dim re     As Object
    Set re = CreateRegExp("\d+")   ' 数字列にマッチ

    Dim result As String
    result = re.Replace("注文番号 12345 の金額は 9800 円", "***")
    Debug.Print result   ' → 注文番号 *** の金額は *** 円

    Set re = Nothing
End Sub

よく使うパターン集

用途パターン
整数^\d+$
小数^\d+(\.\d+)?$
郵便番号^\d{3}-\d{4}$
電話番号(ハイフンあり)^\d{2,4}-\d{2,4}-\d{4}$
メールアドレス(簡易)^[^\s@]+@[^\s@]+\.[^\s@]+$
日付(yyyy/mm/dd)^\d{4}/\d{2}/\d{2}$
HTMLタグ除去<[^>]+>
連続スペース正規化\s+(置換先: " ")

正規表現でよくある誤りとデバッグのコツ

VBAの正規表現(VBScript.RegExp)を使い始めたときに陥りやすい問題と対処法を整理する。

よくある誤り原因対処
TestでTrueになるのに期待した文字列が取れない Testはパターンが「含まれるか」のみ確認する。全文一致させたい場合は^$を使っていない 全体一致には^パターン$を使う。部分一致なら^$は不要
Globalを設定していないので最初の1件しか取れない Global = Falseのとき(デフォルト)はExecuteが最初のマッチだけ返す 複数マッチが必要な場合はre.Global = Trueを設定してからExecuteを呼ぶ
特殊文字(.や*など)をそのままパターンに書く 正規表現では.は任意の1文字に、*は直前文字の0回以上繰り返しに解釈される リテラルとして使いたい場合はバックスラッシュでエスケープする(例:\.
Subマッチ(グループ)の取り出し方が分からない 括弧でグループ化した部分はmatch.SubMatchesコレクションに格納される matches(0).SubMatches(0) で1番目のグループを取り出す

まとめ

VBScript.RegExp を使うと、Like 演算子では困難な複雑なパターンマッチングが実現できます。レイトバインディングで参照設定不要のため配布物にも使いやすい点が魅力です。

次の章では…

PART 10 では ファイル操作 を解説します。FileSystemObject と旧来の Open 文の違い、フォルダ再帰処理のパターンを紹介します。

→ PART 10 — ファイル操作へ