Excel VBAで正規表現の使い方をお探しですね。

広告

Excel VBAで正規表現を使って文字列をスマートに扱う方法

Excel VBAで文字列を処理していると、`InStr`や`Mid`、`Replace`といった基本的な関数だけでは対応しきれない場面に出くわすことがあります。

たとえば、セルに書かれた文章の中から金額だけを取り出したい、ファイル名に含まれる「Rev.03」のような番号を抜き出したい、メールアドレスや電話番号が正しい形式かチェックしたい、といったケースです。

こうした「決まった文字」ではなく「決まった形」を扱いたいときに便利なのが**正規表現(RegExp)**です。

この記事では、Excel VBAで正規表現を使って、複雑な文字列のパターンマッチ・抽出・置換を行う方法を、実務で使いやすい形にまとめて解説していきます。

1. VBAで正規表現を使う準備と基本的な考え方

正規表現ってなに?

正規表現とは、文字列の特徴を「パターン」として表すための記法です。

たとえば「数字が1文字以上続く」は`\d+`、「4桁の年、スラッシュ、2桁の月、スラッシュ、2桁の日」は`\d{4}/\d{2}/\d{2}`のように表現できます。

Excel VBAでは、通常のワークシート関数だけで複雑なパターン抽出をしようとすると大変です。

でも正規表現を使えば、「どこにあるか分からない数値」「表記がバラバラなリビジョン番号」「複数のURL」なども柔軟に扱えるようになります。

単なる検索ではなく、**文字列の「形」を条件にして判定・抽出・置換できる**のが最大のメリットです。

VBAで正規表現を使う2つの方法

VBAで正規表現を使う方法は主に2つあります。

**①事前バインディング(参照設定を使う方法)**
VBEの「ツール」→「参照設定」から「Microsoft VBScript Regular Expressions 5.5」にチェックを入れる方法です。

**②遅延バインディング(CreateObjectを使う方法)**
`CreateObject(“VBScript.RegExp”)`を使う方法です。

参照設定が不要なので、マクロを他のPCや社内の複数環境で共有する場合はこちらの方が扱いやすいです。

まずは、次のようにRegExpオブジェクトを作成する書き方を覚えましょう。

“`vb
Sub RegExpBasic()
Dim re As Object
Set re = CreateObject(“VBScript.RegExp”)

re.Pattern = “\d+”
re.Global = True
re.IgnoreCase = True

Debug.Print re.Test(“注文番号A123”) ‘ True
End Sub
“`

重要な3つのポイント

正規表現を使うときは、次の3つを押さえておきましょう。

– **Pattern**:「何を探すか」を書く
– **Global**:最初の1件だけ探すか、すべて探すか(`True`=すべて、`False`=最初の1件)
– **IgnoreCase**:大文字小文字を区別するか(`True`=区別しない)

`IgnoreCase=True`にしておけば、`Rev`、`rev`、`REV`のような表記ゆれにも対応できます。

注意点:すべての正規表現が使えるわけではない

VBAで使えるVBScript.RegExpは便利ですが、他のプログラミング言語で使える正規表現の機能がすべて使えるわけではありません。

たとえば否定先読み`(?!…)`は使えますが、否定後読み`(?2. Pattern・Global・IgnoreCaseと、Test・Execute・Replaceの使い分け

まず押さえるべき4つのプロパティ

RegExpで最初に覚えるべきプロパティは次の4つです。

| プロパティ | 意味 |
|———|——|
| **Pattern** | 検索条件そのもの |
| **Global** | 最初の1件だけか、全件か |
| **IgnoreCase** | 大文字小文字を区別するか |
| **MultiLine** | 複数行の文字列で`^`と`$`を各行の先頭・末尾として扱うか |

`MultiLine`は、ログや複数行のメモをセルに貼り付けて処理する場合に役立ちます。

ただし、`.`(ドット)は原則として改行には一致しないので、複数行をまたぐ抽出ではパターンの設計に注意が必要です。

目的別に使い分ける3つのメソッド

正規表現を使った処理は、目的によってメソッドを使い分けます。

| メソッド | 戻り値 | 使いどころ |
|————|——–|———–|
| **Test** | True/False | 一致するかどうかのチェック(入力チェックなど) |
| **Execute** | 一致した文字列の集合 | 文字列の抽出 |
| **Replace** | 置換後の文字列 | 文字列の整形やマスキング |

たとえば、電話番号の形式チェックなら`Test`、文章中の金額抽出なら`Execute`、日付表記の変換なら`Replace`という使い分けです。

“`vb
Sub RegExpMethods()
Dim re As Object
Set re = CreateObject(“VBScript.RegExp”)

‘ Testの例:郵便番号の形式チェック
re.Pattern = “\d{3}-\d{4}”
Debug.Print re.Test(“郵便番号は123-4567です”) ‘ True

‘ Executeの例:数字の抽出
re.Pattern = “\d+”
re.Global = True

Dim matches As Object, m As Object
Set matches = re.Execute(“商品Aは1500円、商品Bは2300円です”)

For Each m In matches
Debug.Print m.Value & ” / 位置:” & m.FirstIndex
Next
End Sub
“`

Executeで取得できる情報

`Execute`の戻り値は、MatchCollectionという一致結果の集まりです。

各Matchには次のような情報が入っています。

– **Value**:一致した文字列
– **FirstIndex**:0から始まる位置
– **Length**:文字数
– **SubMatches**:丸括弧`()`で囲んだ部分(キャプチャグループ)に一致した部分

たとえば`”(Rev\.?)(\d+)”`のように書くと、「Rev」部分と数字部分を分けて扱えます。

ファイル名解析や番号抽出でとても便利です。

3. 複雑な文字列から必要な情報を抽出する実務パターン

セルの文章から金額を抜き出す

Excel VBAで正規表現を使う代表的な場面は、セル内の文章から特定の情報を抜き出す処理です。

たとえば注文メールや請求書データでは、こんな風に金額の位置や表記がバラバラなことがあります。

– 「合計¥12,000(税込)」
– 「請求金額は75,600円です」
– 「商品A 3,500円、商品B 1,200円」

関数だけで処理しようとすると、`FIND`や`MID`を何重にも組み合わせる必要があります。

でも正規表現なら、「カンマ区切りを含む数字」という形でまとめて抽出できます。

次の関数は、文字列内から最初に見つかった数値を取り出す例です。

“`vb
Function ExtractFirstNumber(ByVal text As String) As String
Dim re As Object
Set re = CreateObject(“VBScript.RegExp”)

re.Pattern = “-?\d{1,3}(,\d{3})*|-?\d+”
re.Global = False

If re.Test(text) Then
ExtractFirstNumber = re.Execute(text)(0).Value
Else
ExtractFirstNumber = “”
End If
End Function
“`

このパターンは、負の数やカンマ付きの数値にもある程度対応しています。

– `-?`:マイナス記号が0回または1回
– `\d{1,3}(,\d{3})*`:1〜3桁の数字の後に、カンマと3桁数字が0回以上続く

ただし、金額以外にも注文番号や顧客IDが同じ文字列に含まれる場合は、単に数字を取るだけでは誤って抽出してしまう可能性があります。

そんな時は、周辺の文字も条件に含めると精度が上がります。

– `¥\s*(-?\d{1,3}(,\d{3})*)`
– `合計[::]?\s*(\d+)円`

ファイル名からリビジョン番号を取り出す

ファイル管理では、ファイル名からリビジョン番号やバージョン番号を抽出する処理もよくあります。

– 「設計書_Rev1.xlsx」
– 「仕様書_rev.02.xlsx」
– 「資料_REV003_確定版.xlsm」

こんな風に表記が揺れる場合でも、`IgnoreCase=True`と`\.?`を組み合わせると柔軟に対応できます。

次の例では、Revの後ろに任意のドットがあり、その後に続く数字をキャプチャグループで取り出しています。

“`vb
Function ExtractRevNumber(ByVal fileName As String) As String
Dim re As Object, matches As Object
Set re = CreateObject(“VBScript.RegExp”)

re.Pattern = “\bRev\.?\s*(\d+)\b”
re.IgnoreCase = True
re.Global = False

If re.Test(fileName) Then
Set matches = re.Execute(fileName)
ExtractRevNumber = matches(0).SubMatches(0)
Else
ExtractRevNumber = “”
End If
End Function
“`

`SubMatches(0)`には、パターン内の1つ目の括弧`(\d+)`に一致した数字部分だけが入ります。

`Rev.02`なら`02`、`REV003`なら`003`を取得できます。

ここで`\b`は「単語の境界」を表します。

これを使うことで、`Revision`のような単語の一部に誤って一致しにくくする工夫ができます。

実務での調整のコツ

実務では、命名規則が部署や案件によって異なります。

最初から万能な正規表現を作ろうとするより、実際のファイル名サンプルを集めてパターンを調整する方が安定します。

4. 置換・マスキング・注意点まで押さえて安全に運用する

Replaceで文字列を整形する

RegExpの`Replace`を使うと、単純な文字列置換では難しい整形ができます。

– 連続する空白を1つにまとめる
– 日付の区切りを変える
– 電話番号やメールアドレスの一部を伏せる

特に便利なのが、キャプチャグループを置換後の文字列で再利用する「後方参照」です。

VBAのRegExpでは、置換文字列側で`$1`、`$2`のように書くことで、括弧で取得した部分を利用できます。

“`vb
Sub ReplaceDateFormat()
Dim re As Object
Set re = CreateObject(“VBScript.RegExp”)

re.Pattern = “(\d{4})/(\d{2})/(\d{2})”
re.Global = True

Debug.Print re.Replace(“締切は2025/12/31です”, “$1年$2月$3日”)
‘ 結果:締切は2025年12月31日です
End Sub
“`

個人情報をマスキングする

個人情報を含むデータを扱う場合は、マスキング処理にも正規表現が役立ちます。

たとえば電話番号の末尾4桁だけを伏せたい場合、前半部分と末尾部分を分けてキャプチャし、置換後に前半だけを残します。

“`vb
Function MaskPhone(ByVal text As String) As String
Dim re As Object
Set re = CreateObject(“VBScript.RegExp”)

re.Pattern = “(0\d{1,4}-\d{1,4}-)(\d{4})”
re.Global = True

MaskPhone = re.Replace(text, “$1****”)
End Function
“`

メールアドレスも同様に、ユーザー名の先頭数文字とドメインだけを残す処理が可能です。

マスキング処理の注意点

ただし、正規表現によるマスキングはパターンに一致したものだけが対象です。

想定外の形式が混在していると伏せ漏れが起こります。

個人情報を扱う場合は、処理後の確認や例外データの検出もセットで考える必要があります。

大量データを処理するときの工夫

大量のセルを処理する場合、ループのたびに`CreateObject`でRegExpを作成すると無駄が増えます。

同じパターンを繰り返し使うなら、ループの外で一度だけ作成して再利用する方が効率的です。

“`vb
Sub ProcessManyRows()
Dim re As Object
Set re = CreateObject(“VBScript.RegExp”)
re.Pattern = “\d+”
re.Global = True

Dim i As Long
For i = 1 To 1000
‘ 同じreオブジェクトを使い回す
If re.Test(Cells(i, 1).Value) Then
‘ 処理
End If
Next i
End Sub
“`

コードを読みやすくする工夫

正規表現は短く書ける反面、後から読む人には意図が伝わりにくいことがあります。

実務コードでは、次のような工夫をすると保守しやすくなります。

– パターンの意味をコメントで残す
– テスト用のサンプル文字列を用意しておく

“`vb
‘ パターン:Revの後にドット(省略可)+数字
‘ 例:Rev1、Rev.02、REV003
re.Pattern = “\bRev\.?\s*(\d+)\b”
“`

VBScript.RegExpの将来性について

最後に、VBScript.RegExpの将来性についても触れておきます。

MicrosoftはVBScriptの非推奨化を進めているため、長期運用するシステムでは将来的に影響を受ける可能性があります。

現時点のExcel VBAでは`CreateObject(“VBScript.RegExp”)`が広く使われていますが、将来的なOffice環境やセキュリティポリシーによっては代替手段を検討する必要があるかもしれません。

とはいえ、現在の業務効率化ではRegExpが有効な場面は多く、文字列のパターンマッチ・抽出・置換を学ぶ価値は十分にあります。

まとめ

Excel VBAで正規表現を使うと、複雑な文字列処理がグッと楽になります。

基本の流れはこの3つです。

1. **Test**で判定
2. **Execute**で抽出
3. **Replace**で置換

まずは金額抽出やRev番号取得など、身近な処理から導入してみてください。

きっとExcel VBAの文字列処理を大きく効率化できるはずです。

広告