2015-10-15 71 views
4

我在Excel VBA中使用Microsoft正則表達式引擎。我對正則表達式很陌生,但我現在有一個模式工作。我需要擴展它,並且遇到麻煩。這是我到目前爲止的代碼:Excel中的正則表達式VBA

Sub ImportFromDTD() 

Dim sDTDFile As Variant 
Dim ffile As Long 
Dim sLines() As String 
Dim i As Long 
Dim Reg1 As RegExp 
Dim M1 As MatchCollection 
Dim M As Match 
Dim myRange As Range 

Set Reg1 = New RegExp 

ffile = FreeFile 

sDTDFile = Application.GetOpenFilename("DTD Files,*.XML", , _ 
"Browse for file to be imported") 

If sDTDFile = False Then Exit Sub '(user cancelled import file browser) 


Open sDTDFile For Input Access Read As #ffile 
    Lines = Split(Input$(LOF(ffile), #ffile), vbNewLine) 
Close #ffile 

Cells(1, 2) = "From DTD" 
J = 2 

For i = 0 To UBound(Lines) 

    'Debug.Print "Line"; i; "="; Lines(i) 

    With Reg1 
     '.Pattern = "(\<\!ELEMENT\s)(\w*)(\s*\(\#\w*\)\s*\>)" 
     .Pattern = "(\<\!ELEMENT\s)(\w*)(\s*\(\#\w*\)\s*\>)" 

     .Global = True 
     .MultiLine = True 
     .IgnoreCase = False 
    End With 

    If Reg1.Test(Lines(i)) Then 
    Set M1 = Reg1.Execute(Lines(i)) 
    For Each M In M1 
     sExtract = M.SubMatches(1) 
     sExtract = Replace(sExtract, Chr(13), "") 
     Cells(J, 2) = sExtract 
     J = J + 1 
     'Debug.Print sExtract 
    Next M 
    End If 
Next i 

Set Reg1 = Nothing 

End Sub 

目前,我對匹配的一組數據是這樣的:

<!ELEMENT DealNumber (#PCDATA) > 

,並提取Dealnumber,但現在,我需要添加像數據另一場比賽這樣的:

<!ELEMENT DealParties (DealParty+) > 

,只是提取Dealparty沒有的括號和+

我一直在使用這個作爲參考,這真棒,但我仍然有點困惑。 How to use Regular Expressions (Regex) in Microsoft Excel both in-cell and loops

編輯

我遇到了必須匹配上了一些新的情況。

Extract Deal 
<!ELEMENT Deal (DealNumber,DealType,DealParties) > 

Extract DealParty the ?,CR are throwing me off 
<!ELEMENT DealParty (PartyType,CustomerID,CustomerName,CentralCustomerID?, 
      LiabilityPercent,AgentInd,FacilityNo?,PartyReferenceNo?, 
      PartyAddlReferenceNo?,PartyEffectiveDate?,FeeRate?,ChargeType?) > 

Extract Deals 
<!ELEMENT Deals (Deal*) > 

回答

1

您可以使用此Regex模式;

.Pattern = "\<\!ELEMENT\s+(\w+)\s+\((#\w+|(\w+)\+)\)\s+\>" 
  1. 該部分

(#\w+|(\w+)\+)

說匹配

#A-Z0-9
一個-Z0-9 +

括號內。

即匹配任一

(#PCDATA)
(DealParty +)

驗證整個字符串

  • 然後,子匹配是用於提取DealNumber進行第一次有效匹配,DealParty for theoth呃有效匹配
  • 下面編輯的代碼 - 記子匹配現在是M.submatches(0)

    Sub ImportFromDTD() 
    
    Dim sDTDFile As Variant 
    Dim ffile As Long 
    Dim sLines() As String 
    Dim i As Long 
    Dim Reg1 As RegExp 
    Dim M1 As MatchCollection 
    Dim M As Match 
    Dim myRange As Range 
    
    Set Reg1 = New RegExp 
    J = 1 
    
    strIn = "<!ELEMENT Deal12Number (#PCDATA) > <!ELEMENT DealParties (DealParty+) >" 
    
    With Reg1 
         .Pattern = "\<\!ELEMENT\s+(\w+)\s+\((#\w+|(\w+)\+)\)\s+\>" 
         .Global = True 
         .MultiLine = True 
         .IgnoreCase = False 
    End With 
    
    If Reg1.Test(strIn) Then 
        Set M1 = Reg1.Execute(strIn) 
        For Each M In M1 
         sExtract = M.SubMatches(2) 
         If Len(sExtract) = 0 Then sExtract = M.SubMatches(0) 
         sExtract = Replace(sExtract, Chr(13), "") 
         Cells(J, 2) = sExtract 
         J = J + 1 
        Next M 
    End If 
    
    Set Reg1 = Nothing 
    
    End Sub 
    
    +0

    謝謝你的帖子,這是我的問題的確切答案。從那以後,我遇到了一些我需要的比賽。其中之一是多線,我無法獲得匹配的模式。我一整天都在regex101網站上工作。我編輯了我的原始文章以包含它們。我想我可能無法在一種模式中完成所有的事情。 –

    +0

    我只是想問一個新的問題的額外比賽。謝謝你的幫助! –

    +0

    嗨佈雷特。你可以看看我的新帖子嗎?它被埋得很快,因爲我覺得非常荒謬的原因而被降級。 [第二次嘗試](http://stackoverflow.com/questions/33215467) –

    3

    看着你的模式,你有太多的捕獲組。您只想捕獲PCDATADealParty。嘗試改變你的模式:

    With Reg1 
         .Pattern = "\<!ELEMENT\s+\w+\s+\(\W*(\w+)\W*\)" 
    
         .Global = True 
         .MultiLine = True 
         .IgnoreCase = False 
        End With 
    

    這裏是存根(stub):Regex101

    +0

    它沒有工作。當我運行它時,它會停止在'sExtract = M.SubMatches(1)'上,如果我將光標放在它上面,我會得到'<無效的過程調用或參數>和'.pattern <對象變量或塊變量沒有設置「我改變的唯一的事情就是模式。 –

    +0

    我剛剛意識到你以爲我想提取'PCDATA'而不是這種情況。我已經更新了我的問題。 –

    +0

    您編輯的問題仍然讓我感到困惑。你有像'<!ELEMENT x(y)>'這樣的行。你想得到什麼? 'x','y'還是兩者兼而有之? –