正規表現(RegExp)
VBA で文字列処理を行う際、単純な検索や置換では対応できない複雑なパターンマッチングが必要になることがあります。そんなときに威力を発揮するのが 正規表現(RegExp) です。
正規表現を使えば、メールアドレスの形式チェック、電話番号の抽出、特定パターンの文字列置換など、高度な文字列操作を効率的に実現できます。
この記事では、VBA で正規表現を使用するための RegExp オブジェクト について、基本から実践的な活用例まで詳しく解説します。
正規表現が必要となるシチュエーション
実務では、以下のような場面で正規表現が威力を発揮します:
- 入力値の検証: メールアドレス、電話番号、郵便番号などの形式チェック
- データの抽出: HTML やテキストから特定パターンの文字列を取得
- 複雑な置換: 特定のパターンに一致する部分だけを別の形式に変換
- ログファイルの解析: 日付や IP アドレスなど特定形式のデータを抽出
- データクレンジング: 不要な文字や空白を一括削除
正規表現は、InStr や Replace 関数では難しい「パターンに基づくマッチング」を可能にします。
RegExp オブジェクトの基本
RegExp オブジェクトの生成方法
VBA で正規表現を使用するには、VBScript.RegExp オブジェクトを生成します。生成方法は 2 つあります。
方法 1:参照設定を使用する方法(事前バインディング)
VBA エディタで「ツール」→「参照設定」から Microsoft VBScript Regular Expressions 5.5 にチェックを入れます。
Sub RegExpEarlyBinding()
' 参照設定が必要
Dim re As RegExp
Set re = New RegExp
re.Pattern = "\d+"
Debug.Print re.Test("abc123") ' True
End Sub
方法 2:CreateObject を使用する方法(遅延バインディング)
参照設定なしで使用できる方法です。汎用性が高いため、こちらが推奨されます。
Sub RegExpLateBinding()
' 参照設定不要
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
re.Pattern = "\d+"
Debug.Print re.Test("abc123") ' True
End Sub
CreateObject を使用する方法は、参照設定が不要なため、他の環境でマクロを共有する際にも問題が起きにくいです。
RegExp の主要プロパティ
RegExp オブジェクトには、以下の重要なプロパティがあります。
| プロパティ | 説明 | 既定値 |
|---|---|---|
Pattern | 検索する正規表現パターン | なし |
Global | 文字列全体を検索するか | False |
IgnoreCase | 大文字小文字を区別しないか | False |
MultiLine | 複数行モードを有効にするか | False |
Pattern プロパティ
検索に使用する正規表現パターンを指定します。
Sub PatternExample()
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
' 数字のパターン
re.Pattern = "\d+"
Debug.Print re.Test("Order123") ' True
' メールアドレスのパターン
re.Pattern = "[\w\.-]+@[\w\.-]+\.\w+"
Debug.Print re.Test("[email protected]") ' True
End Sub
Global プロパティ
Global を True に設定すると、文字列全体を検索して すべての一致 を返します。False(既定値)の場合は 最初の一致 のみを返します。
Sub GlobalExample()
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
re.Pattern = "\d+"
' Global = False(既定):最初の一致のみ
re.Global = False
Dim matches As Object
Set matches = re.Execute("abc123def456ghi789")
Debug.Print "Global=False: " & matches.Count & " 件" ' 1 件
' Global = True:すべての一致
re.Global = True
Set matches = re.Execute("abc123def456ghi789")
Debug.Print "Global=True: " & matches.Count & " 件" ' 3 件
End Sub
IgnoreCase プロパティ
IgnoreCase を True に設定すると、大文字小文字を区別せずに検索します。
Sub IgnoreCaseExample()
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
re.Pattern = "hello"
' IgnoreCase = False(既定):大文字小文字を区別
re.IgnoreCase = False
Debug.Print re.Test("HELLO") ' False
' IgnoreCase = True:大文字小文字を区別しない
re.IgnoreCase = True
Debug.Print re.Test("HELLO") ' True
End Sub
RegExp の主要メソッド
RegExp オブジェクトには、3 つの主要なメソッドがあります。
| メソッド | 説明 | 戻り値 |
|---|---|---|
Test | パターンが一致するかチェック | Boolean |
Execute | 一致した文字列を取得 | MatchCollection |
Replace | 一致した文字列を置換 | String |
Test メソッド:パターンの一致をチェック
Test メソッドは、文字列がパターンに一致するかどうかを True または False で返します。入力値の検証に最適です。
Sub TestMethodExample()
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
' 電話番号の形式チェック(例:090-1234-5678)
re.Pattern = "^0\d{1,4}-\d{1,4}-\d{4}$"
Debug.Print re.Test("090-1234-5678") ' True
Debug.Print re.Test("03-1234-5678") ' True
Debug.Print re.Test("1234567890") ' False
Debug.Print re.Test("abc-defg-hijk") ' False
End Sub
Execute メソッド:一致した文字列を取得
Execute メソッドは、パターンに一致した文字列を MatchCollection オブジェクト として返します。各一致は Match オブジェクト として格納されています。
Sub ExecuteMethodExample()
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
re.Pattern = "\d+"
re.Global = True
Dim text As String
text = "商品A: 1500円、商品B: 2300円、商品C: 980円"
Dim matches As Object
Set matches = re.Execute(text)
Dim m As Object
For Each m In matches
Debug.Print "一致: " & m.Value & " (位置: " & m.FirstIndex & ")"
Next m
' 出力:
' 一致: 1500 (位置: 5)
' 一致: 2300 (位置: 16)
' 一致: 980 (位置: 27)
End Sub
Match オブジェクトのプロパティ
| プロパティ | 説明 |
|---|---|
Value | 一致した文字列 |
FirstIndex | 一致した位置(0 始まり) |
Length | 一致した文字列の長さ |
SubMatches | キャプチャグループに一致した文字列集合 |
Replace メソッド:文字列の置換
Replace メソッドは、パターンに一致した部分を指定した文字列で置換します。
Sub ReplaceMethodExample()
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
re.Pattern = "\s+" ' 連続する空白
re.Global = True
Dim text As String
text = "これは テスト 文字列 です"
' 連続する空白を単一の空白に置換
Dim result As String
result = re.Replace(text, " ")
Debug.Print result ' "これは テスト 文字列 です"
End Sub
置換での後方参照
キャプチャグループを使用して、一致した部分を置換文字列で再利用できます。$1、$2 などで参照します。
Sub ReplaceBackreferenceExample()
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
' 日付形式の変換:YYYY/MM/DD → YYYY年MM月DD日
re.Pattern = "(\d{4})/(\d{2})/(\d{2})"
re.Global = True
Dim text As String
text = "期日: 2025/07/02、締切: 2025/12/31"
Dim result As String
result = re.Replace(text, "$1年$2月$3日")
Debug.Print result ' "期日: 2025年07月02日、締切: 2025年12月31日"
End Sub
よく使う正規表現パターン
実務でよく使用する正規表現パターンをまとめました。
数値関連
' 整数
re.Pattern = "^\d+$"
' 小数(正の数)
re.Pattern = "^\d+(\.\d+)?$"
' 負の数を含む整数
re.Pattern = "^-?\d+$"
' 3桁カンマ区切りの数値
re.Pattern = "^\d{1,3}(,\d{3})*$"
連絡先関連
' メールアドレス
re.Pattern = "^[\w\.-]+@[\w\.-]+\.\w+$"
' 電話番号(ハイフンあり)
re.Pattern = "^0\d{1,4}-\d{1,4}-\d{4}$"
' 郵便番号
re.Pattern = "^\d{3}-\d{4}$"
日付・時刻関連
' 日付(YYYY/MM/DD または YYYY-MM-DD)
re.Pattern = "^\d{4}[/-]\d{2}[/-]\d{2}$"
' 時刻(HH:MM:SS)
re.Pattern = "^\d{2}:\d{2}:\d{2}$"
' 日時(YYYY/MM/DD HH:MM:SS)
re.Pattern = "^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}$"
実践的な活用例
例 1:メールアドレスの検証関数
Function IsValidEmail(email As String) As Boolean
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
' メールアドレスのパターン
re.Pattern = "^[\w\.-]+@[\w\.-]+\.[a-zA-Z]{2,}$"
re.IgnoreCase = True
IsValidEmail = re.Test(email)
End Function
Sub TestEmailValidation()
Debug.Print IsValidEmail("[email protected]") ' True
Debug.Print IsValidEmail("[email protected]") ' True
Debug.Print IsValidEmail("invalid-email") ' False
Debug.Print IsValidEmail("@example.com") ' False
End Sub
例 2:テキストから URL を抽出
Sub ExtractURLs()
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
' URL パターン
re.Pattern = "https?://[\w\-\.]+(/[\w\-\./?%&=]*)?"
re.Global = True
re.IgnoreCase = True
Dim text As String
text = "参考サイト: https://www.example.com/page1 と " & _
"http://sub.example.org/path?id=123 をご覧ください。"
Dim matches As Object
Set matches = re.Execute(text)
Debug.Print "検出された URL:"
Dim m As Object
For Each m In matches
Debug.Print " " & m.Value
Next m
' 出力:
' 検出された URL:
' https://www.example.com/page1
' http://sub.example.org/path?id=123
End Sub
例 3:個人情報のマスキング
Function MaskPhoneNumber(text As String) As String
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
' 電話番号パターン(最後の4桁をマスク)
re.Pattern = "(0\d{1,4}-\d{1,4}-)(\d{4})"
re.Global = True
MaskPhoneNumber = re.Replace(text, "$1****")
End Function
Function MaskEmail(text As String) As String
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
' メールアドレスのユーザー名部分をマスク
re.Pattern = "([\w\.-]{1,3})([\w\.-]*)(@[\w\.-]+\.\w+)"
re.Global = True
MaskEmail = re.Replace(text, "$1***$3")
End Function
Sub TestMasking()
Dim text As String
' 電話番号のマスキング
text = "連絡先: 090-1234-5678、自宅: 03-9876-5432"
Debug.Print MaskPhoneNumber(text)
' 出力: 連絡先: 090-1234-****、自宅: 03-9876-****
' メールアドレスのマスキング
text = "メール: [email protected]、予備: [email protected]"
Debug.Print MaskEmail(text)
' 出力: メール: tan***@example.com、予備: yam***@mail.co.jp
End Sub
例 4:CSV データの整形
Sub CleanCSVData()
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
Dim text As String
text = " 田中, 東京都新宿区 , 090-1234-5678 "
' 1. 項目前後の空白を削除
re.Pattern = "\s*,\s*"
re.Global = True
text = re.Replace(text, ",")
' 2. 先頭・末尾の空白を削除
re.Pattern = "^\s+|\s+$"
text = re.Replace(text, "")
Debug.Print text ' "田中,東京都新宿区,090-1234-5678"
End Sub
VBScript.RegExp の廃止予定について
Microsoft は VBScript の廃止を発表しており、将来的に VBScript.RegExp も使用できなくなる可能性があります。Office 365 の VBA では新しい正規表現機能がサポートされていますが、買い切り版 Office では未対応の場合があります。
現時点では VBScript.RegExp が最も広く使われている方法ですが、長期的なプロジェクトでは代替手段の検討も必要です。
正規表現のパフォーマンスに関する注意点
正規表現は強力ですが、使い方によってはパフォーマンスに影響する場合があります。
RegExp オブジェクトの再利用
同じパターンを繰り返し使用する場合は、RegExp オブジェクトを使い回すことで効率が向上します。
' 非効率な例:毎回 RegExp を生成
Sub IneffientExample()
Dim i As Long
For i = 1 To 10000
Dim re As Object
Set re = CreateObject("VBScript.RegExp") ' 毎回生成
re.Pattern = "\d+"
' ... 処理
Next i
End Sub
' 効率的な例:RegExp を再利用
Sub EfficientExample()
Dim re As Object
Set re = CreateObject("VBScript.RegExp") ' 一度だけ生成
re.Pattern = "\d+"
Dim i As Long
For i = 1 To 10000
' re を再利用
' ... 処理
Next i
End Sub
大量のデータを処理する場合は、RegExp オブジェクトをモジュールレベルの変数として定義し、複数のプロシージャで共有することも検討してください。
まとめ
VBA の正規表現(RegExp)について、以下の内容を解説しました。
- RegExp オブジェクトの生成方法:
CreateObject("VBScript.RegExp")による遅延バインディングが推奨 - 主要プロパティ:
Pattern、Global、IgnoreCase、MultiLine - 主要メソッド:
Test(検証)、Execute(抽出)、Replace(置換) - 実践的な活用例: メールアドレス検証、URL 抽出、個人情報マスキング、データ整形
正規表現を使いこなすことで、複雑な文字列操作を効率的に行えるようになります。最初は難しく感じるかもしれませんが、よく使うパターンを覚えて少しずつ応用範囲を広げていくことで、VBA での文字列処理の幅が大きく広がります。