![]()
筆箱にVBAのカンニングペーパーを入れる係のみすくです。こんにちは。
Excel VBAで正規表現を使うとき、特にサブマッチを使うとき、
書かなければいけないことが多くて面倒なので、
簡単に使えるようにクラス化してみました。
ツール > 参照設定 > Microsoft VBscript Regular expressions 5.5

Option Explicit
Public Function iterator() As IIterator
End Function
Option Explicit
Public Function hasNext() As Boolean
End Function
Public Function nextItem() As Object
End Function
Option Explicit
Implements IAggregate
'ツール > 参照設定 > microsoft vbscript regular expressions
Private regEx As New RegExp
Private regMc As MatchCollection
Private regMatch As Match
'-------------------------------------------------------------------------------
' デストラクタ
'-------------------------------------------------------------------------------
Private Sub Class_Terminate()
Set regEx = Nothing
Set regMc = Nothing
Set regMatch = Nothing
End Sub
'-------------------------------------------------------------------------------
' iterator
'-------------------------------------------------------------------------------
Public Function IAggregate_iterator() As IIterator
Dim res As New RegExpIterator
Call res.init(Me)
Set IAggregate_iterator = res
End Function
'-------------------------------------------------------------------------------
' 【処 理 名】プロパティ設定
' 【引 数】isGlobal[Boolean] :True 文字列全体に検索が適用
' False 最初の一致だけに検索が適用
' isIgnoreCase[Boolean]:True 検索時に大文字と小文字を区別する
' False 検索時に大文字と小文字を区別しない
' 【返 却 値】なし
' 【処理概要】RegExpオブジェクトのプロパティを設定。
'-------------------------------------------------------------------------------
Public Sub setProperties(ByVal isGlobal As Boolean, ByVal isIgnoreCase As Boolean)
With regEx
.Global = isGlobal
.IgnoreCase = isIgnoreCase
End With
End Sub
'-------------------------------------------------------------------------------
' 【処 理 名】検索
' 【引 数】target[String] :検索対象文字列
' pattern[String]:検索する文字列(正規表現パターン)
' 【返 却 値】なし
' 【処理概要】指定された文字列を正規表現で検索
'-------------------------------------------------------------------------------
Public Sub execute(ByVal target As String, ByVal pattern As String)
regEx.pattern = pattern
Set regMc = regEx.execute(target)
End Sub
'-------------------------------------------------------------------------------
' 【処 理 名】パターン一致判定
' 【引 数】target[String] :検索対象文字列
' pattern[String]:検索する文字列(正規表現パターン)
' 【返 却 値】なし
' 【処理概要】指定された文字列を正規表現で検索し、パターンに一致する文字列が
' 検索されたかどうかを示すブール (Boolean) 値を返却。
'-------------------------------------------------------------------------------
Public Function test(ByVal target As String, ByVal pattern As String) As Boolean
regEx.pattern = pattern
test = regEx.test(target)
End Function
'-------------------------------------------------------------------------------
' 【処 理 名】置換
' 【引 数】target[String]:検索および置換の対象となるテキスト文字列
' before[String]:検索する文字列(正規表現パターン)
' after[String] :置換するテキスト文字列
' 【返 却 値】置換後文字列
' 【処理概要】正規表現による検索で見つかったテキストを置換します。
'-------------------------------------------------------------------------------
Public Function Replace(ByVal target As String, ByVal before As String, ByVal after As String) As String
regEx.pattern = before
Replace = regEx.Replace(target, after)
End Function
'-------------------------------------------------------------------------------
' 【処 理 名】マッチ件数取得
' 【引 数】なし
' 【返 却 値】検索マッチ件数
' 【処理概要】executeメソッドで検索したマッチ件数を返却
'-------------------------------------------------------------------------------
Public Function getCount() As Long
getCount = regMc.Count
End Function
'-------------------------------------------------------------------------------
' 【処 理 名】マッチ文字列取得
' 【引 数】index[Long]:検索でマッチした結果のインデックス
' 【返 却 値】マッチ
' 【処理概要】executeメソッドで検索したマッチした該当indexのマッチを返却
'-------------------------------------------------------------------------------
Public Function getRegMatchAt(ByVal index As Long) As Object
Set getRegMatchAt = regMc.Item(index)
End Function
Option Explicit
Implements IIterator
Private reg As New RegExpAggregate
Private index As Long
'-------------------------------------------------------------------------------
' 【処 理 名】次エレメント存在チェック
' 【引 数】なし
' 【返 却 値】ブール値
' 【処理概要】collectionに次のエレメントがあるのブール (Boolean) 値を返却。
'-------------------------------------------------------------------------------
Public Function IIterator_hasNext() As Boolean
If index < reg.getCount Then
IIterator_hasNext = True
Else
IIterator_hasNext = False
End If
End Function
'-------------------------------------------------------------------------------
' 【処 理 名】次エレメント取得
' 【引 数】なし
' 【返 却 値】エレメント
' 【処理概要】collectionのエレメントを返却。
'-------------------------------------------------------------------------------
Public Function IIterator_nextItem() As Object
Set IIterator_nextItem = reg.getRegMatchAt(index)
index = index + 1
End Function
'-------------------------------------------------------------------------------
' 【処 理 名】初期化
' 【引 数】RegExpAggregate[IAggregate] ConcreteAggregate
' 【返 却 値】なし
' 【処理概要】イテレータを初期化する
'-------------------------------------------------------------------------------
Public Sub init(ByVal RegExpAggregate As IAggregate)
Set reg = RegExpAggregate
index = 0
End Sub
こんな感じで使う
Option Explicit
Public Sub main()
Dim sql As String
Dim ptn As String
Dim reg As New RegExpAggregate
Dim it As New IIterator
Dim regMatch As Match
sql = "SELECT HOGE, FUGA FROM TBL_A;SELECT FUGA, HOGE FROM TBL_B;"
ptn = "(SELECT)\s+(.*?)\s+FROM\s+(.*?);"
Call reg.setProperties(True, True)
If reg.test(sql, ptn) Then
Debug.Print "True"
Else
Debug.Print "False"
End If
Call reg.execute(sql, ptn)
Set it = reg.IAggregate_iterator
Do While (it.hasNext)
Set regMatch = it.nextItem
Debug.Print regMatch.SubMatches(2)
'サブマッチを使わない場合はregMatch.valueで値を取得できる
Loop
Call reg.Replace(sql, "TBL_A", "TBL_C")
End Sub
setProperties()を設定しなければ、regExpオブジェクトのデフォルトで検索します。
Regular Expression オブジェクトのプロパティ
| Global | 検索文字列全体についてのパターンとの一致を検索するか、最初の一致だけを検索するかを示すブール (Boolean) 値を設定します。 | True | 文字列全体に検索が適用 |
| False | 最初の一致だけに検索が適用 | ||
| IgnoreCase | パターン検索で大文字と小文字を区別するかどうかを示すブール (Boolean) 値を設定します。 | True | 検索するときに大文字と小文字を区別する |
| False | 検索するときに大文字と小文字を区別しない | ||
| Pattern | 検索される正規表現のパターンを設定します。値の取得も可能です。 | 正規表現のパターンの記述には、特別な文字およびエスケープ シーケンスが使用されます。 | |
参考
micro soft|Developer Network RegExp オブジェクト
最近のコメント

コメントを残す