はじめに
VBAでは正規表現が使いにくいので、関数を作りました。常に文字列配列として返すので、サブマッチの取り出しが可能です。
使い方
- 引数1 str : 対象文字列
- 引数2 pattern : パターンを文字列として指定する。大文字と小文字は区別しない
- 戻り値 : 文字列配列として返す。要素(0)はマッチした全体、要素(1)以上はサブマッチ文字列となる。マッチするものがない場合は、要素(0)が、空文字列 "" になる。マッチするものが複数ある場合は、最後にマッチしたものを返す
- 使用例 : パスからフォルダ部分とファイル名を分離する
使用例
path = "C:\Users\Public\Documents\abc.txt"
reSeparatePath = "^(.+)\\(.+?)$" '\はメタ文字なので要エスケープ
Dim output() As String '戻り値用変数
output = myMatchA(path, reSeparatePath) '関数の呼び出し
For i = 0 To UBound(output)
Debug.Print i, output(i)
Next
結果
0 C:\Users\Public\Documents\abc.txt
1 C:\Users\Public\Documents
2 abc.txt
コード
このコードを実行するには、参照設定「Microsoft VBScript Regular Expressions 5.5」が必要です。
Function myMatchA(ByVal str As String, ByVal pattern As String) As String()
Dim rv() As String '戻り値格納用
'Microsoft VBScript Regular Expressions 5.5
Dim re As New regexp
re.Global = True
re.IgnoreCase = True
re.pattern = pattern
'Test
If Not (re.test(str)) Then
ReDim rv(1)
rv(0) = ""
myMatchA = rv()
Exit Function
End If
Dim mc As MatchCollection 'ヒット文字列の集合
Set mc = re.Execute(str)
Dim m As Match '個々のヒット文字列
Dim submatchesCount As Long
For Each m In mc '最後にマッチしたものを返す
submatchesCount = m.SubMatches.Count
ReDim rv(submatchesCount)
rv(0) = m.Value 'マッチ全体
Dim i As Integer
For i = 1 To m.SubMatches.Count
rv(i) = m.SubMatches(i - 1) 'm.SubMatchesでは 最初の添字は0
Next
Next
myMatchA = rv()
End Function
最後に
近々、VBScriptが廃止されるそうです。たぶん、このコードは使えなくなると思いますが、それまでには対策を考えます。
参考資料
正規表現関係
- VBAで正規表現を使用する #VBA - Qiita
https://qiita.com/kisa/items/74085046abc6c0ac2607 - Office TANAKA - Excel VBA Tips[正規表現によるマッチング]
http://officetanaka.net/excel/vba/tips/tips38.htm
配列関係
- 【VBA入門】配列まとめ(宣言・初期化、反復処理、コピー、結合) │ TechMania
https://techmania.jp/blog/excel-vba-array/ - VBAで配列を引数・戻り値にする方法 #VBA - Qiita
https://qiita.com/ryosuke0825/items/93eb8a284eb5dba59f29