RegExpオブジェクトの機能

 先の節で正規表現の簡単な使用例をみてみましたが、Accessで正規表現を扱うにはVBAの使用が必須となります。さらにRegExpオブジェクトというものを介して操作することとなりますので、「.」とか「^」といったメタキャラクタをいくら覚えてもそれだけでは全く扱えません。
 そこで、まずはRegExpオブジェクトに関する設定とはたらきについてここでみてみます。なかなか難しいですがReplaceメソッドだけでもかなり応用が利きますので、まずはその辺りから覚えていけばよいと思います。

RegExpオブジェクトの使用例

 例として先の節で用いたコードを再掲します。これは「文字列中の半角数字をすべて『*』に置き換える」というユーザー定義関数です。
 これによりRegExpオブジェクトを用いる際の基本的な流れを今一度確認してみます。

Function reg_replace(arg As Variant) As Variant
    
    'RegExpオブジェクト生成
    Dim reg_exp As Object
    Set reg_exp = CreateObject("VBScript.RegExp")

    'プロパティ設定
    With reg_exp
        .Global = True      '文字列全体を対象とする
        .IgnoreCase = False '大文字と小文字を区別する
        .Pattern = "[0-9]"  'マッチング対象を表すパターン
    End With

    '対象文字列がNullでなければReplaceメソッド実行、戻り値設定
    If IsNull(arg) Then
        reg_replace = Null
    Else
        reg_replace = reg_exp.Replace(Nz(arg), "*")
    End If

    Set reg_exp = Nothing

End Function

 おおまかな手順としては
  ・RegExpオブジェクトを生成する
  ・プロパティを設定する
  ・メソッドによりマッチングを実行し結果を得る
となっています。

 このうち、オブジェクトを生成するDimとSet文は特に変えようのないものですので、慣れないうちは深く考えずこういうものとお考え下さい。
 プロパティはメソッドの実行に向けて詳細をカスタマイズするもので、Global,IgnoreCase,Patternの3種があります。この例ではすべて設定しています。
 メソッドは具体的に結果を得るための動作で、Test,Replace,Executeの3種があります。この例は文字の置換を目的としていますのでReplaceメソッドのみを用いています。
 以下ではプロパティとメソッドの詳細について説明します。

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

プロパティ

 3種のプロパティによりマッチングのための事前設定を行うことができます。

プロパティ設定値と意味
GlobalTrue…文字列全体に対しマッチングを行う
False…文字列中にマッチするものが1つあったらそこでマッチングを終える(既定値)
IgnoreCaseTrue…大文字と小文字を区別しない
False…大文字と小文字を区別する(既定値)
Pattern 文字列中のマッチングさせたい部分を表す正規表現パターン(下記は設定値の一例)
[0-9]…半角数字
[0-90-9]半角数字と全角数字
[^あ-ん]…ひらがな以外

 Globalプロパティについては、例えば「半角数字をすべて記号に置き換えたい」といった場合はTrueにする必要があります。一方で「半角数字が1文字でも含まれているか知りたい」といった場合は1回マッチするものが見つかったらあとは調べる必要がありませんのでFalseで足ります。
 IgnoreCaseプロパティについては、実際にTrueで使うことはあまりないように思います。Patternプロパティの設定によって大文字と小文字の両方をマッチングの対象とすることも、どちらかだけを対象とすることも自由にできるため、このプロパティで敢えて縛る必要性が薄いことが理由です。
 Pattrenプロパティに用いる文字や設定例は多岐にわたりますので改めて説明します。ここでは「[0-9]は半角数字を表している」といった程度の理解で十分です。

メソッド

 目的に応じた3種類のメソッドが用意されており、これによりマッチングを実行して結果を得ます。
 このうちMatchとReplaceは普通の関数のように値を返します。
 Executeは結果をMatchCollectionコレクションに返しますので、そちらのプロパティから結果を参照する必要があります。

メソッド意味
Match 文字列中に、正規表現パターンにマッチする部分があるかを表すブール値を返します(あればTrue、なければFalse)
 対象となる文字列を引数として指定する必要があります
Replace 文字列中の、正規表現パターンにマッチする部分を、指定した文字列に置き換えた結果を返します
 対象となる文字列と置換先文字列(マッチする部分を何に置き換えるか)の2つの引数を指定する必要があります
Execute 文字列中の、正規表現パターンにマッチする部分の文字列や文字位置などの情報を返します
 他の2つのメソッドと異なり、結果はさまざまな情報を収めたMatchCollectionコレクションとして返されます

 注意点としてはReplaceメソッドはReplace関数に似ているものの引数は2つであり(Replace関数では3つ)、Replace関数でいうところの第2引数(置換対象文字列)はPatternプロパティにより設定するという点が挙げられます。

MatchCollectionコレクションとMatchオブジェクト

 上記の3種のメソッドのうちExecuteメソッドは若干特殊で、結果はMatchCollectionというコレクションに返されます。これはMatchオブジェクト(パターンにマッチする文字列が1つあるごとに1つでき、それぞれがマッチした文字列やその位置などを格納している)の集まりです。
 ちょっと複雑ですが実例を見て覚えた方が早いかと思いますのでまずは適当に読み進めてください。

MatchCollectionコレクションのプロパティ

 MatchCollectionはMatchオブジェクトの集まりですが、これ自体が2つのプロパティを持っています。
 参照のみ可能です。

プロパティ意味
Count コレクション内の要素の数
 つまりMatchオブジェクトの数であり、パターンにマッチした文字列の数にあたります
Item インデックス(0,1,2…)を用いてコレクション内の個々の要素を指定できます
 具体例として「Item(2)」は3番目にマッチした文字列に関する情報を記録したMatchオブジェクトを表します
 指定の方法としては下記のようにEachループを用いる方法もあります

Matchオブジェクトのプロパティ

 MatchオブジェクトのプロパティはExecuteメソッドによりマッチした文字列に関する情報を格納しています。
 参照のみ可能です。

プロパティ意味
FirstIndex パターンにマッチした文字列のうち最初の文字の位置
 ただし1文字目のときは0となり、2文字目のときは1になり、n文字目のときはn-1となります
Length マッチした文字列の長さ(文字数)
Value マッチした文字列そのもの

使用例

 以下はMatchCollectionコレクションとMatchオブジェクトを用いるコードの例です。
 これは「文字列中の半角数字の数とそれぞれの位置を示す文字列を返す」というユーザー定義関数です。
 前半のプロパティ設定までは上記の例と同じです。後半にてExecuteメソッドを実行し、MatchCollectionコレクション(reg_matches)のcountプロパティから半角数字の個数を取得しています。また、Eachループを用いて各Matchオブジェクト(i)のFirstIndexプロパティから半角数字の位置を取得しています。そしてそれらを文字列として結合し、最終的に戻り値としています。

Function reg_execute(arg As Variant) As Variant

    'RegExpオブジェクト生成
    Dim reg_exp As Object
    Set reg_exp = CreateObject("VBScript.RegExp")

    'プロパティ設定
    With reg_exp
        .Global = True      '文字列全体を対象とする
        .IgnoreCase = False '大文字と小文字を区別する
        .Pattern = "[0-9]"  'マッチング対象を表すパターン
    End With

    'MatchCollectionコレクションとMatchオブジェクト
    Dim reg_matches As Object, i As Object
    Dim txt As Variant
     
    '対象文字列がNullでなければExecuteメソッド実行、各プロパティから戻り値設定
    If IsNull(arg) Then
        reg_execute = Null
    Else
        Set reg_matches = reg_exp.Execute(arg)
        txt = reg_matches.Count & "個:"
            For Each i In reg_matches
                txt = txt & i.FirstIndex + 1 & "文字目"
            Next i
        reg_execute = txt
    End If
    
    Set reg_exp = Nothing

End Function

 この関数の実行例として

reg_execute("山田さんの体温は37度8分です")

の戻り値は

3個:9文字目10文字目12文字目

となります。

MatchCollectionコレクションの名称について

 ちなみにですが、MatchCollectionコレクションはしばしばMatchesコレクションと称されます。しかし正しくはMatchCollectionというコレクションです。試しに事前バインド(詳しくはこちらを参照ください)を採用して「Dim ~ New Matches」と宣言するとエラーになります。