VBA / VBS で正規表現による関数を使った置き換え

Pocket

JScriptのString.replaceメソッドは非常に便利だ。
置き換え文字列に、「文字列」ではなく「関数」が使えるところが意外と使える。
[cc lang=”js” line_numbers=”false” noborder=”true”]
“test0 test1”.replace(
/\w+(\d)/g,
function($0,$1){return (Number($1)+1).toString();})
[/cc]
てな具合に。

普段はWSHではVBSなんぞ使ったりしないが、
たまにどうしてもVBAやVBSを使わなくてはならない場合がある。
そんなときにそれっぽい動作をする様なのを、
不完全ながら自作してみた。

[cc lang=”vb” lines=”-1″]
Option Explicit

Function REReplace(strSearch As String, _
ByRef objRE As Object, _
strFuncName As String) As String
Dim oMatches, Match
Dim strOut As String
Dim nCursor As Integer
Dim objScript
Set objScript = CreateObject(“ScriptControl”)

Set oMatches = objRE.Execute(strSearch)

nCursor = 0
strOut = “”
For Each Match In oMatches
Dim args() As String
Dim i As Integer
ReDim Preserve args(Match.SubMatches.Count)
args(0) = Match.Value
For i = 0 To Match.SubMatches.Count – 1
args(i + 1) = Match.SubMatches(i)
Next i

If nCursor < Match.FirstIndex Then strOut = strOut & Mid(strSearch, nCursor + 1, Match.FirstIndex - nCursor) nCursor = Match.FirstIndex End If nCursor = nCursor + Match.Length ' VBSならEval使う strOut = strOut & CallByName(Me, strFuncName, VbMethod, args) Next REReplace = strOut End Function Function reptest(args) As String reptest = CStr(Val(args(1)) + 1) End Function [/cc] これを適当なクラスモジュールにして使う。 標準モジュールだとCallByNameが使えないので… ホントVBAは糞だな!!w 呼び出すときは、 [cc lang="vb" line_numbers="false" noborder="true"] Dim RE As Object Dim RERep Dim strRet As String Set RE = CreateObject("VBScript.RegExp") RE.Pattern = "\w+([\d])" RE.ignorecase = True RE.Global = True ' RERepという変数にクラスのインスタンスを作っておく. Set RERep = New RegExpReplace strRet = RERep.REReplace("test test1 test2", RE, "reptest") [/cc] のような感じで。 reptestの代わりに、必要なメソッドを追記してやって、 その名前をREReplaceメソッドに渡してやればOK。 置き換え関数を複数分ける必要がなければ、CallByName呼んでいるところを、 直接関数を呼ぶように変更してやればよろし。

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください