VBAで文字列を扱っていると、
「メールアドレスだけを抜き出したい」「数字だけ取り出したい」
といった場面があるかと思います。
そんなときに役立つのが「正規表現」です。
この記事では、VBAで正規表現を使う方法と、よくある活用例をわかりやすく解説します。
初心者の方でもすぐ使えるように、サンプルコード付きで丁寧に紹介いたします。
-著者情報-
名前:Utatane
VBA(マクロ)歴:3年
Excel使用歴:15年以上
ひとこと:初心者だった当時に戻った気持ちになって解説いたします
※わかりやすさを重視しております。厳密には解釈が異なる場合がありますことをご了承ください。
VBA(Excelマクロ)の正規表現とは?
正規表現(Regular Expression)とは、文字列のパターンを指定して検索や抽出、置換ができる仕組みです。
例えば「a123」という文字列があったとします。
ここから数字である「123」だけを抽出したり、「123」を「456」に置換することができます。
メールアドレスのドメイン名を変更したり、電話番号の数字だけを抽出したりするのに便利です。
では早速、正規表現の書き方や使い方を見ていきましょう。
正規表現の書き方・使い方
正規表現の使い方を説明をする前に、まずは参照設定を追加しましょう。
正規表現を使うための機能が詰まった(RegExp)を参照できるように設定する大切な作業です。
例えるなら、国語辞典や英和辞典を買ってくるみたいなものでしょうか…。
この作業を忘れるとうまく動作しない場合がありますので、必ず済ませておきましょう。
参照設定の追加
追加手順は以下のとおりです。
VBAProject画面上部のメニューから「挿入」→「参照設定」をクリックします。

参照設定画面が開きますので、
中ほどの「Microsoft VBScript Regular Expressions 5.5」にチェックを入れて、「OK」をクリックします。

これで参照設定の追加が完了しました。
では正規表現の書き方・使い方を解説いたします。
簡単な使い方
前提知識{マクロの基礎・作り方から実行まで}
前提知識{「Debug.Print」で値を表示させる方法}
前提知識{変数の宣言や使い方}
前提知識{条件分岐(If)}
まずは簡単な使い方として、文字列に数字が含まれるかを判定した例です。
下記VBAコードを見てください。
少し長いですが、1つ1つ解説していきます。
Sub 数字が含まれているかを判定するマクロ()
Dim regEx As Object
Set regEx = CreateObject("VBScript.RegExp")
regEx.Pattern = "\d" ' 数字が1つでも含まれるか
regEx.IgnoreCase = True ' 大文字小文字を無視
regEx.Global = False ' 最初の一致だけでOK
If regEx.Test("Utatane760") Then
Debug.Print "数字が含まれています"
Else
Debug.Print "数字は含まれていません"
End If
End Sub

変数の作成と正規表現の設定
コードの1行目はプロシージャなので解説を割愛します。
3行目~8行目で変数の作成と正規表現の設定をしております。
Dim regEx As Object
Set regEx = CreateObject("VBScript.RegExp")
regEx.Pattern = "\d" ' 数字が1つでも含まれるか
regEx.IgnoreCase = True ' 大文字小文字を無視
regEx.Global = False ' 最初の一致だけでOK
まずは3行目にて、オブジェクト型の変数を宣言しています。
4行目では、変数を正規表現用の機能(VBScript.RegExp)を代入しております。
6~8行目にて正規表現の設定をしています。
「Pattern」や「IgnoreCase」はプロパティです。
これで細かな設定ができます。
「\d」はエスケープシーケンスといって、文字の分類などを表したものです。
今回は数字のみを判定する「\d」を指定しています。
上記のコードを含めたよく使うプロパティ一覧とエスケープシーケンス一覧を載せておきます。
プロパティ一覧
主なプロパティを記載いたします。
- Pattern:検索するパターン(正規表現文字列)
- IgnoreCase:大文字と小文字を区別しないか(Trueで区別しない)
- Global:すべての一致を対象にするか(Trueですべての一致を対象)
- Test:一致するかを判定(True/False)
- Execute:一致した部分を取得(MatchCollection)
- Replace:一致した部分を置換
エスケープシーケンス一覧
Patternでよく使うエスケープシーケンスを記載いたします。
エスケープシーケンス | 役割 | マッチするものの例 | マッチしないものの例 |
\d | 一桁の半角数字 | 1, 5 | a, 10, 5 |
\D | 数字以外の一文字 | a, -, ( | 1, 7 |
\w | 英数字と半角_ | a, 1, _ | -, あ |
\W | \w以外の一文字 | -, あ | a, 1, _ |
\s | 空白系の一文字 | スペース, タブ, 改行 | 1, a, -, あ |
\S | \s以外の一文字 | 1, a, -, あ | スペース, タブ, 改行 |
. | 改行以外の一文字 | 1, a, -, あ | 改行 |
^ | 行頭(前方一致) | ^uta → utatane | ^uta → zutatane |
$ | 行末(後方一致) | ane$ → utatane | ane$ → utatane1 |
+ | 直前の文字が1回以上 | n+→utatane | n+→utatame |
{○,} | ○回以上 | \d{3,}→123, 6789 | \d{3,}→1, abc |
{,○} | ○回以下 | \d{,3}→123, 89 | \d{,3}→1234, abc |
{○} | ちょうど○回 | \d{3}→123, 789 | \d{3}→12, abc |
{□,○} | □回以上○回以下 | \d{2,3}→123, 89 | \d{2,3}→1, abc |
| | Or(複数条件) | ab|cd→ab, cd | ef, ghi |
\ | メタ文字のエスケープ | \.→「.」そのもの | (特別な意味としての「.」) |
エスケープシーケンスを組み合わせることで、より多くのパターンを指定できます。
例えば「^\d」と指定すれば、数字から始まっているかを判定することができます。
パターンとの一致判定
If regEx.Test("Utatane760") Then
Debug.Print "数字が含まれています"
Else
Debug.Print "数字は含まれていません"
End If
10行目でパターンと文字列が一致するかを判定しています。
判定するには「Test」プロパティを使います。
()内に判定する文字列を入れ、前に「regEx.(パターンが入ったオブジェクト)」をつけます。
あとはIfを使った条件分岐で、一致する場合と一致しない場合の処理を記述して完成です。
実践的な応用例
ここからは、より実践的な応用例を紹介いたします。
数字のみを抽出
前提知識{Valueについて}
前提知識{ループ処理(For Each)}
下記VBAコードは、文字列の中から電話番号に該当する部分を抽出した例です。
Sub 電話番号の抽出()
Dim regEx As Object
Set regEx = New RegExp
regEx.Pattern = "\d+" ' 数字をすべて抽出
regEx.Global = True ' すべての一致を対象にする
regEx.IgnoreCase = True ' 大文字小文字を無視
Dim matches As Object
Set matches = regEx.Execute("電話番号は09011111111です。")
Dim m As Object
For Each m In matches
Debug.Print m.Value ' → 09011111111
Next
End Sub

今回は文字を抽出したいので、「Test」ではなく「Execute」を使っています(10行目)
数値のみを抽出するパターンを指定しているので、変数「matches」には「09011111111」が入ります。
しかしながら、変数「matches」は集合オブジェクトなので、そのままではイミディエイトウィンドウに表示することができません。
わかりやすく言えば、1人のグループといったところでしょうか…。
グループ名は表示できるけど、個人名は表示できないようなものと思ってください。
なので、個人名を表示するには、グループから個人を呼び出す必要があります。
For Each(13行目)を使って集合オブジェクトから単体オブジェクトを呼び出し(グループから個人を呼び出し)しています。
これで個人名である変数の中身が表示できるようになります。
文字列を置換
今回はメールアドレスのドメイン名を変更した例です。
下記VBAコードを見てください。
Sub メアドのドメイン変更()
Dim regEx As Object
Set regEx = CreateObject("VBScript.RegExp")
'パターン:ユーザー名 @ ドメイン名
regEx.Pattern = "([\w\.-]+)@([\w\.-]+\.\w+)" ' (英数字半角_.-)@(英数字半角_.-).(英数字半角_)を指定
regEx.Global = True ' すべての一致を対象
regEx.IgnoreCase = True ' 大文字小文字を無視
Dim src As String
src = "user1@old-domain.com; user2@old-domain.com"
Dim result As String
result = regEx.Replace(src, "$1@new-domain.jp")
Debug.Print result
' → user1@new-domain.jp; user2@new-domain.jp
End Sub

今回は文字列の置換をしたいので「Replace」プロパティ(14行目)を使っています。
「Replace」の第2引数で、変数内の文字列を「$1@new.com」に置換するように指定しています。
【引数とは?】
引数は「引き渡す数(引き渡す値)」のことで、Replaceの()内に渡す値を指します。
引数として「置換前の文字列」と「置換後の文字列」を渡すと、「置換された文字列」を私たちが受け取ります。
この受け取る値を「返り値(戻り値)」といいます。
例えば、魚屋さんにアジの3枚おろしを作ってもらいたい場合は、アジとお金を渡して3枚おろしを受け取ります。
アジとお金が引数、3枚おろしが返り値といったところでしょうか。
「$1」は最初の( )で取得したメアドの@より前=ユーザー名です(User1、User2)
今回は集合オブジェクトではなくString型なので、個人を呼び出す必要はありません。
最後に
VBA(Excelマクロ)の正規表現について解説いたしました。
当ブログでは、VBAマクロやPythonなど、時間を生み出すプログラミング術を公開しております。
この記事がわかりやすいと感じた方は、他の記事も読んでいってください。
最後までお読みいただき、ありがとうございました。がんばってください!