JScriptのString.replaceメソッドは非常に便利だ。
置き換え文字列に、「文字列」ではなく「関数」が使えるところが意外と使える。
"test0 test1".replace(
/\w+(\d)/g,
function($0,$1){return (Number($1)+1).toString();})
てな具合に。
普段はWSHではVBSなんぞ使ったりしないが、
たまにどうしてもVBAやVBSを使わなくてはならない場合がある。
そんなときにそれっぽい動作をする様なのを、
不完全ながら自作してみた。
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
これを適当なクラスモジュールにして使う。
標準モジュールだとCallByNameが使えないので…
ホントVBAは糞だな!!w
呼び出すときは、
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")
のような感じで。
reptestの代わりに、必要なメソッドを追記してやって、
その名前をREReplaceメソッドに渡してやればOK。
置き換え関数を複数分ける必要がなければ、CallByName呼んでいるところを、
直接関数を呼ぶように変更してやればよろし。