2009-05-31 83 views
1

我想通過Regex解析VB6代碼。然而對於正則表達式來說我還是遇到了一些關於正則表達式的問題。目前,我有問題,認識到這些結構:正則表達式跨越多行/識別註釋行

' Subs 
' Sub Test 
Private Sub Test(ByVal x as Integer) 
    'Private Sub Test(ByVal y as Integer) 
    Dim dummy as String 
    dummy = "Private Sub Test(ByVal y as Integer)" 
End Sub 

我已經基本上這2個問題:如何編寫,小組定義相匹配,包括它的定義之上的所有commment(空)線的正則表達式?我怎樣才能防止被評論禁用或包含在字符串中的子定義不匹配? 另外,我需要支持這些跨越多行的定義,像這樣的:

' Subs 
' Sub Test 
Private Function Test2(_ 
    ByVal x as Integer _ 
) As Long 
    'Private Sub Test(ByVal y as Integer) 
    Dim dummy as String 
    dummy = "Private Sub Test(ByVal y as Integer)" 
End Function 

任何暗示將不勝appreaciated。我提出的解決方案不適用於多行或捕獲不止一個Sub定義。然後由於貪婪匹配而匹配到最後End Sub的結尾。

我在C#中的嘗試目前看起來是這樣的:

(('(?<comment>[\S \t]+[\n\r]+))*((?<accessmodifier>(Private|Public))\s+_?)(?<functiontype>(Sub|Function))\s+_?(?<name>[\S]+)\((?<parameters>[\S \t]*)\)([ \t]+As[ \t]+(?<returntype>\w+))?)|(?<endfunction>End (Sub|Function)) 

我使用MultilineSinglelineIgnoreCaseExplicitCapture

感謝您的幫助!

回答

2

你爲什麼要解析這段代碼?如果你想創建你自己的編譯器,你需要的不僅僅是正則表達式。如果你正在編寫一個語法突出和提前完成的編輯器,正則表達式可以在第一個,但不是第二個上做得很好。

這就是說,我看到你的正則表達式最大的問題是你沒有正確處理連續線。這:\s+_?匹配一個或多個空白字符,可選地後跟一個下劃線。但是,如果有下劃線,則應在後面跟上一個換行符,而這個換行符並不匹配。這很容易補救 - \s+(_\s+)? - 但我不知道你需要具體的。我懷疑這個:[\s_]+也可以。

至於避免在註釋和字符串中出現明顯的子/函數聲明,最簡單的方法是僅在左邊距匹配它們,可能有一些製表符或空格用於縮進。我知道這是作弊,但對於你正在做的事情來說,它可能已經足夠好了。當我爲EditPad Pro編寫Java file navigation scheme時,我非常依賴那個技巧。你不能用正則表達式來做這種事,而不用大量的噱頭和簡化的假設。試試這個正則表達式:

^(?>('(?<comment>.*[\n\r]+))*) 
[ \t]*(?<accessmodifier>(Private|Public)) 
[\s_]+(?<functiontype>(Sub|Function)) 
[\s_]+(?<name>\S+) 
[\s_]*\((?<parameters>[^()]*)\) 
([\s_]+As[\s_]+(?<returntype>\w+))? 
| 
^[ \t]*(?<endfunction>End (Sub|Function))

當然,你需要重新組裝它。它應該與Multiline,IgnoreCaseExplicitCapture選項編譯,但不是Singleline

2

我懷疑這是不可能的,除了最簡單的情況。使用正則表達式您無法解析遞歸結構,並且語言(如VB)將具有遞歸功能。有關更多信息,請參閱this CodingHorror blog entry

除非你有非常簡單的情況,否則我認爲某種形式的解析器將成爲前進的方向。

1

你知道,最終有一段時間,正則表達式還不夠。在這個級別解析是其中之一。

請考慮寫一個簡單的實際解析器,也許使用遞歸下降。

1

不要試圖寫一個正則表達式來爲你做這件事(它本質上不能)。你需要的是一個解析器。可能最簡單的解決方案是使用recursive descent parser。我不使用C#,但快速搜索出現了Spart

0

鑑於Visual Basic的複雜性和複雜性,您可能需要使用標記器/解析器來解析代碼。你不能依靠的正則表達式;)

爲什麼它的價值,VB formal grammar is available here。玩的開心!