正規表現ワークシート関数の独自実装

#始めに

Excelのワークシート関数で正規表現が使いたいことがあるが、標準のワークシート関数には無い。ネットで探せばExcel VBAを利用した正規表現ワークシート関数の実装を掲載しているサイトはいろいろある。しかし、自分が使いやすい実装ではなかったりするので自作してみた。

#構文
`Regex(Source, Pattern[, MatchIndex[, SubMatchIndex]])`

| 名前            | 必須 | データ型 | 説明              |
|:----------------|:---:|:-------:|:------------------|
| `Source`        | Yes | String  | 対象の文字列       |
| `Pattern`       | Yes | String  | 正規表現パターン   |
| `MatchIndex`    | No  | Long    | 取得したい一致文字列のインデックス（1～）     |
| `SubMatchIndex` | No  | Long    | 取得したい部分一致文字列のインデックス（1～） |

#説明

このワークシート関数は、対象の文字列に対して指定の正規表現パターンで正規表現を実行し、その結果を返します。引数の指定方法によりこのワークシート関数が返す結果は異なります。このワークシート関数が返す結果は次の３つです。

| 返す内容                       | MatchIndex | SubMatchIndex |
|:------------------------------|:----------:|:--------------|
| 一致する文字列の件数を返す      | = 0 or 省略 | = 0 or 省略   |
| 一致する文字列を返す            | > 0        | = 0 or 省略   |
| 一致する文字列の部分文字列を返す | > 0        | > 0           |

正規表現のオプション（g, i, m）は指定できません。gオプションはMatchIndex引数の値により自動的に設定します。
#コード
```vbnet
'※[Microsoft VBScript Regular Expressions 5.5]の参照設定が必要
Public Function Regex( _
        Source As String, _
        Pattern As String, _
        Optional MatchIndex As Long = 0, _
        Optional SubMatchIndex As Long = 0 _
    )

    Dim Matches As MatchCollection
    Dim SubMatches As SubMatches

    If MatchIndex = 0 Then
        If SubMatchIndex = 0 Then
            '一致する件数を返す
            With New RegExp
                .Global = True
                .IgnoreCase = False
                .MultiLine = False
                .Pattern = Pattern
                Regex = .Execute(Source).Count
            End With
        Else
            Regex = CVErr(XlCVError.xlErrValue)
        End If
    ElseIf MatchIndex > 0 Then
        If SubMatchIndex = 0 Then
            '一致する文字列を返す
            With New RegExp
                .Global = MatchIndex > 1
                .IgnoreCase = False
                .MultiLine = False
                .Pattern = Pattern
                Set Matches = .Execute(Source)
                If MatchIndex <= Matches.Count Then
                    Regex = Matches(MatchIndex - 1).Value
                Else
                    Regex = ""
                End If
            End With
        ElseIf SubMatchIndex > 0 Then
            '一致する部分文字列を返す
            With New RegExp
                .Global = MatchIndex > 1
                .IgnoreCase = False
                .MultiLine = False
                .Pattern = Pattern
                Set Matches = .Execute(Source)
                If MatchIndex <= Matches.Count Then
                    Set SubMatches = Matches(MatchIndex - 1).SubMatches
                    If SubMatchIndex <= SubMatches.Count Then
                        Regex = CStr(SubMatches(SubMatchIndex - 1))
                    Else
                        Regex = ""
                    End If
                Else
                    Regex = ""
                End If
            End With
        Else
            Regex = CVErr(XlCVError.xlErrValue)
        End If
    Else
        Regex = CVErr(XlCVError.xlErrValue)
    End If
End Function
```

#使い方
↓こんな感じで使います。

![image](https://qiita-image-store.s3.amazonaws.com/0/85927/2c9e85e8-b245-e03f-14d4-4a7dddad911f.png)

#応用
* このワークシート関数をにちょっと手を加えれば、正規表現オプション（i, m）を指定できるワークシート関数が出来上がり。
* 参照設定が必要なんて面倒くさい！参照設定って何ですか？って人の為に`CreateObject("VBScript.RegExp")`を使った実装もいいかも。これならコピペで使えます。