正規表現によるマッチング


VBAから正規表現を使うには、VBScriptが便利です。ただし、正規表現をサポートしているVBScriptはVer5.0からですから、IE5.0がインストールされているパソコンでないと使えません。

VBScriptの中で正規表現エンジンを提供しているのはRegExpオブジェクトです。参照設定によるEarly Bindingか、CreateObject関数を使ったLate Bindingで参照します。ここではLate Bindingによるサンプルを紹介します。

まずは、正規表現で使用するオブジェクトとプロパティやメソッドを整理しましょう。

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

Patternプロパティ 正規表現で使用するパターンを設定します。.*や[A-Z]、(田中|鈴木)などの文字列です。
IgnoreCaseプロパティ 大文字と小文字を区別しないときにTrueを設定します。デフォルトはFalseです。
Globalプロパティ 検索対象の文字列内で、文字列全体を検索するにはTrueを設定します。デフォルトではFalseです。
Testメソッド 正規表現によるマッチングを行います。パターンと一致した場合はTrueを返します。
Replaceメソッド 検索文字列の中で正規表現によるマッチングを行い、成功するとそのマッチした部分を置換文字列と置き換えます。
Executeメソッド Testメソッドはマッチングが成功したかどうかをTrue/Falseで返します。Executeメソッドは、マッチングの結果をMatchesコレクションとして返します。MatchesコレクションはMatchオブジェクトの集合です。

MatchesコレクションはExecuteメソッドによって返されるコレクションです。Matchesコレクションには0個以上のMatchオブジェクトが含まれます。つまり、Executeメソッドの結果返ってきたMatchesコレクションにMatchオブジェクトが存在しなかったら、マッチングは失敗したということです。

Matchesコレクションのプロパティとメソッド

Countプロパティ Matchesコレクション内でMatchオブジェクトの個数を返します。これを調べるとマッチングの成功/失敗がわかります。
Itemプロパティ いわゆる一般的なコレクションのItemプロパティです。普通はMatches(1)のようにアクセスするので使うことはないでしょう。

Matchオブジェクトのプロパティとメソッド

FirstIndexプロパティ 最初にマッチングに成功した位置を返します。文字列の先頭は0から始まります。
Lengthプロパティ マッチした文字列の長さを返します。
Valueプロパティ マッチした文字列を返します。

主なメタ文字とエスケープシーケンス

title title
^ 文字列の先頭
$ 文字列の末尾
\n 改行
. 改行を除く任意の1文字
* 直前のパターンの0回以上の繰り返し
+ 直前のパターンの1回以上の繰り返し
? 直前のパターンが0回または1回現れる
\d 任意の数値
\D 任意の数値以外の文字
\s 任意のスペース文字
\S 任意のスペース以外の文字
() パターンのグループ化
| パターンの論理和
[] キャラクタクラス

Excelでの使用例

正規表現は、いかに適切なパターンを作り出すかがポイントです。その考え方はExcelやVBAだからといって特別ではありません。ここでは、RegExpオブジェクトの基本的な使い方を紹介します。たとえば、こんなイメージです。あとはみなさんの発想しだいですね。

次のコードは、アクティブシート内でSUM関数を使っているセルの背景を赤色に塗りつぶします。SUMPRODUCT関数は無視します。

Sub Sample1()
    Dim RE, strPattern As String, r As Range
    Set RE = CreateObject("VBScript.RegExp")
    strPattern = "SUM\("
    With RE
        .Pattern = strPattern       ''検索パターンを設定
        .IgnoreCase = True          ''大文字と小文字を区別しない
        .Global = True              ''文字列全体を検索
        For Each r In ActiveSheet.UsedRange
            If .Test(r.Formula) Then r.Interior.ColorIndex = 3
        Next r
    End With
    Set RE = Nothing
End Sub

次のコードは、セル範囲A1:A10に入力された名前のうち「田中または田口で始まり」「最後が子または美で終わる」名前だけを表示します。

Sub Sample2()
    Dim RE, strPattern As String, i As Long, msg As String, reMatch
    Set RE = CreateObject("VBScript.RegExp")
    strPattern = "^田(中|口).*(子|美)$"
    With RE
        .Pattern = strPattern
        .IgnoreCase = True
        .Global = True
        For i = 1 To 10
            Set reMatch = .Execute(Cells(i, 1))
            If reMatch.Count > 0 Then
                msg = msg & reMatch(0).Value & vbCrLf
            End If
        Next i
    End With
    MsgBox msg
    Set reMatch = Nothing
    Set RE = Nothing
End Sub