2017-03-22 20 views
3

私がJavaで持っていた方法をVBAに変換することは、予想以上に困難になっています。名前付きグループを持つVBAと正規表現

私はそれはいくつかの研究の後に、VBAでサポートされて表示されないというオブジェクトグループを使用していますhere

を見つけることができる正規表現を持っています。私は機能への入力に基づいて異なるフォーマットにIPアドレスをフォーマットするExcel用の関数を記述しようとしています。

さまざまなパターンをキャプチャするには、名前付きグループを使用して回避するにはどうすればよいですか?

Function formatIP(item As String, displayType As String) As String 
'displayTypes CIDR,MASK,RANGE 

'Set theRegEx = CreateObject("VBScript.RegExp") 

Dim theRegEx As New RegExp 


With theRegEx 
.Global = True 
.MultiLine = False 
.IgnoreCase = False 
.Pattern = "(?<address>\d{1,3}(?:\.\d{1,3}){2}\.(?<FromSeg>\d{1,3}))(?:(?:\/|\s+\/\s+)(?<CIDR>\d{1,2})|(?:-|\s+to\s+)(?<ToSeg>\d{1,3}(?![\d\.]))|(?:-|\s*to\s+)(?<ToIP>\d{1,3}(?:\.\d{1,3}){3})|\s+(?<Mask>25\d(?:\.\d{1,3}){3})|\s*)?" 
.Execute (item) 


End With 


'Set MyMatches = theRegEx.Execute(item) 
Debug.Print "SubMatches.Count: " & MyMatches.item(0).SubMatches.Count 
If MyMatches.Count <> 0 Then 
    With MyMatches 
     For myMatchCt = 0 To .Count - 1 
       Debug.Print "myMatchCt: " & myMatchCt 
       For subMtCt = 0 To .item(subMtCt).SubMatches.Count - 1 
        Debug.Print "subMtCt: " & subMtCt 
        Debug.Print ("," &  .item(myMatchCt).SubMatches.item(subMtCt)) 
       Next 
     Next 
    End With 
Else 
Debug.Print "No Matches" 
End If 

formatIP = "" 
End Function 

答えて

4

あなたはしません。 VBAは名前付きグループをサポートしていないVBScript風の正規表現を使用します。代わりに番号付きキャプチャグループを使用します。

これは、正規表現のパターンをデバッグするのがずっと難しくなります。回避策を尋ねてから、Visual Studioにアクセスできる場合は、COMを表示できる小さなクラスライブラリを作成することができます。あなたのVBAコードで参照して使うことができるネット風味のある正規表現(JavaのほうがVBScriptのものに似ています)APIです。

欠点は、そのライブラリの展開を管理する必要があることです。

あなたはあなたを助けるためにExpresso(30日後に必要な登録で無料なし所属)のようなツールを使用し、その後、VBScriptの-正規表現に固執するを持っている場合。

Expresso regex analyzer

エスプレッソは、しかし、.NETの正規表現を理解し、それはあなたのパターンが完全に有効と見なします。

または、VBScriptの-正規表現を理解し、VBA(免責事項では動作しませんあなたのパターンのどの部分(複数可)を教えてくれますRubberduckさん正規表現アシスタント機能、使用:私はそのプロジェクトを維持 - それは無料ですが、オープンソースと積極的に維持):

Rubberduck regex analyzer

enter image description here

幸運!

1

RegexBuddyは、Java正規表現をvbScript互換の正規表現に変換できるプログラムです。それはあなたがあなたのリンクに掲載の例と同じ出力が得られますが、番号が付けではなく、名前のキャプチャグループで次のように

(\d{1,3}(?:\.\d{1,3}){2}\.(\d{1,3}))(?:(?:/|\s+/\s+)(\d{1,2})|(?:-|\s+to\s+)(\d{1,3}(?![\d.]))|(?:-|\s*to\s+)(\d{1,3}(?:\.\d{1,3}){3})|\s+(25\d(?:\.\d{1,3}){3})|\s*)? 

それは、番号のグループに出力を提供します:

1 Address 
2 FromSeg 
3 CIDR 
4 ToSeg 
5 ToIP 

debug.printリンクの例を使用して、マクロの出力が正しいように見えます。

+0

これは、私がそれが起こっていると思っていたよりも簡単になりました。誰かが私にループを使って一致する結果を拾い読みすることができますか?私はさまざまな方法が使われているのを見ています。 –

+0

@JamieSnipesおそらく 'For Each object in Collection'は' For I = 0 to .count-1'よりも少し効率的です。あなたのサブミットでは、とにかくカウンターを維持する必要があります。 –

+0

For eachループはオブジェクトコレクションを反復するForループよりもはるかに高速です。 –

関連する問題