2013-03-17 75 views
1

我將通過示例代碼解釋我的情況。我的功能GetDox看起來很接近,但它仍然不完整。這是一個測試代碼。使用RegExp選擇範圍

'test begin... 
'<dox> 
' <member type="Public Sub" name="Increment" return="void"> 
' <param type="Integer" name="nBase" out="true" /> 
' <param type="Integer" name="nStep" out="false" /> 
' <purpose> 
'  purpose here... 
' </purpose> 
' </member> 
' <member ... /> 
'</dox> 
'other comments here... 
Public Sub Increment(nBase, nStep) 'some example content 
    nBase = nBase + nStep 
End Sub 
'<Unwonted_Item /> 

Dim source 'reading the same file just for simplification 
With CreateObject("Scripting.FileSystemObject") 
    With .OpenTextFile(WScript.ScriptFullName, 1, False) 
     source = .ReadAll 
    End With 
End With 
result = GetDox(source) 
WScript.Echo result 'display our result 

Function GetDox(sCode) 'unfinished function 
    Dim regEx, Match, Matches, mVal, sEnd 
    sEnd = "</dox>" & vbNewLine 
    Set regEx = New RegExp 
    regEx.Pattern = "('<dox>\n|'\s*<.*)" 'my ugly pattern 
    regEx.IgnoreCase = True 
    regEx.Global = True 
    Set Matches = regEx.Execute(sCode) 
    For Each Match In Matches 
     mVal = Match.Value 
     mVal = Replace(mVal, vbCr, vbNewLine) 
     mVal = Right(mVal, Len(mVal) - 1) 
     GetDox = GetDox & mVal 
     If mVal = sEnd Then Exit For 
    Next 
End Function 

這就是我得到:

<dox> 
    <member type="Public Sub" name="Increment" return="void"> 
    <param type="Integer" name="nBase" out="true" /> 
    <param type="Integer" name="nStep" out="false" /> 
    <purpose> 
    </purpose> 
    </member> 
    <member ... /> 
</dox> 

而這正是我需要的:

<dox> 
    <member type="Public Sub" name="Increment" return="void"> 
    <param type="Integer" name="nBase" out="true" /> 
    <param type="Integer" name="nStep" out="false" /> 
    <purpose> 
     purpose here... 
    </purpose> 
    </member> 
    <member ... /> 
</dox> 

與行 「的宗旨在這裏......」 失蹤了,我知道,整個RegExp.Pattern語法很薄弱。我只想選擇以<dox>開頭並以</dox>結尾的整個內容,其中包括所有內容,但我堅持使用模式語法。

P.S.有這麼優秀的幫助(感謝所有),這是我現在的工作職能:

Function GetDox(sCode) 
    GetDox = vbNullString 
    With New RegExp 
     .Pattern = "<dox>[\s\S]*?</dox>" 
     .IgnoreCase = True 
     .Global  = False 
     With .Execute(sCode) 
      If .Count = 0 Then Exit Function 
      GetDox = .Item(0).Value 
     End With 
     .Pattern = "^'" 
     .Global  = True 
     .Multiline = True 
     GetDox = .Replace(GetDox, "") 
    End With 
End Function 
+1

爲什麼你使用正則表達式而不是XPath等? – 2013-03-17 08:40:59

+0

@FrankSchmitt - 我提取了一個綁定在.VBS文件中的XML作爲註釋,就這些了。 – 2013-03-17 16:16:12

回答

2

我會先移除前導單引號:

regEx.Pattern = "^'" 
regEx.Global = True 
sCode = regEx.Replace(sCode, "") 

然後提取XML文本:

regEx.Pattern = "<dox>[\s\S]*?</dox>" 
regEx.Global = False 
regEx.IgnoreCase = True 
Set m = regEx.Execute(sCode) 
If m.Count > 0 Then GetDox = m(0).Value 

這之後,你應該讀取XML成DOM tree作進一步處理:

Set xml = CreateObject("Msxml2.DOMDocument.6.0") 
xml.async = False 
xml.loadXML result 

如果您的XML位於單獨的文件中,則應直接從該文件加載XML並使用XPath表達式提取節點,如@FrankSchmitt在其評論中所建議的那樣。

Set xml = CreateObject("Msxml2.DOMDocument.6.0") 
xml.async = False 
xml.load "C:\path\to\your.xml" 

Set nodes = xml.selectNodes("//dox") 

XML不是面向行的,不應該像解析一樣。如果處理不當,事情可能會以有趣的方式突破。

+0

非常感謝您的詳細解答!在調用'.Replace'之前,我設置了'.Multiline = True'來刪除單引號。 – 2013-03-17 16:10:52

1

要修復您的代碼,你可以使用這個表達式:('<dox>\n|'\s*[\S \t]*)demo

另一種方式來做到這一點會得到你需要的一切先用<dox>[\s\S]+?<\/dox>然後應用取代了它:
搜索:^',無所事事取代

,或者清除前導空格:
搜索:^'\s*的東西就沒有更換demo

+0

非常有用,謝謝+1鏈接! – 2013-03-17 16:05:46