2011-03-21 52 views
5

我有一個用C#編寫的WPF項目,爲了獲得關於外部依賴關係的一些信息,我需要解析一個VB6腳本。腳本的位置變化和其含量的變化,但主要的代碼我很感興趣會是以下格式:在.NET中解析VB6代碼

Select Case Fields("blah").Value 
    Case "Some value" 
     Fields("other blah").List = Lists("a list name") 
    ... 
End Select 

我需要從這種提取物,當現場「嗒嗒」設置爲「某個值','other blah'字段的列表更改爲列出'列表名稱'。我試着用一個VB6解析器作爲.NET庫進行搜索,但還沒有發現任何東西。有可能得到像this one這樣的答案,我應該使用正則表達式在VB6腳本中找到這樣的代碼,並提取我需要的數據?代碼在子例程中找到,這樣我就不能傳入'blah','some value'並返回'other blah','列表名稱'。我無法控制這個VB6腳本的內容。

+0

參見[這個問題](http://stackoverflow.com/questions/1129149/visual-basic-6-0-language-syntax) 。例如,[VBScript語法](http://stackoverflow.com/questions/1129149/visual-basic-6-0-language-syntax/1129425#1129425)和第三方商業[VB6解析器] (http://stackoverflow.com/questions/1129149/visual-basic-6-0-language-syntax/1129163#1129163)。 – MarkJ 2011-03-22 12:08:36

回答

4

您可以通過幾個步驟解析它。請注意,正則表達式會遺漏字符串和註釋,請小心使用。

首先,我們將使用一個輔助類爲Fields("Target").List = Lists("Value")行:

class ListData 
{ 
    public string Target { get; set; } 
    public string Value { get; set; } 
} 

輸出模式:

string patternSelectCase = @" 
Select\s+Case\s+Fields\(""(?<CaseField>[\w\s]+)""\)\.Value 
(?<Cases>.*?) 
End\s+Select 
"; 

string patternCase = @" 
Case\s+""(?<Case>[\w\s]+)""\s+ 
(?:Fields\(""(?<Target>[\w\s]+)""\)\.List\s*=\s*Lists\(""(?<Value>[\w\s]+)""\)\s+)* 
"; 

接下來,我們可以嘗試解析兩遍文本(代碼順便說一句,但是相當基本):

MatchCollection matches = Regex.Matches(vb, patternSelectCase, 
     RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | 
     RegexOptions.Singleline); 

Console.WriteLine(matches.Count); 

var data = new Dictionary<String, Dictionary<String, List<ListData>>>(); 
foreach (Match match in matches) 
{ 
    var caseData = new Dictionary<String, List<ListData>>(); 
    string caseField = match.Groups["CaseField"].Value; 
    string cases = match.Groups["Cases"].Value; 

    MatchCollection casesMatches = Regex.Matches(cases, patternCase, 
      RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | 
      RegexOptions.Singleline); 
    foreach (Match caseMatch in casesMatches) 
    { 
     string caseTitle = caseMatch.Groups["Case"].Value; 
     var targetCaptures = caseMatch.Groups["Target"].Captures.Cast<Capture>(); 
     var valueCaptures = caseMatch.Groups["Value"].Captures.Cast<Capture>(); 
     caseData.Add(caseTitle, targetCaptures.Zip(valueCaptures, (t, v) => 
      new ListData 
      { 
       Target = t.Value, 
       Value = v.Value 
      }).ToList()); 
    } 

    data.Add(caseField, caseData); 
} 

現在你有一本包含所有數據的字典。例如:

string s = data["foo"]["Some value2"].First().Value; 

這裏有一個工作示例:https://gist.github.com/880148

+0

謝謝!這些正則表達式比我提出的更好,更徹底。我不得不從http://weblogs.thinktecture.com/cnagel/2010/02/linq-with-net-4-zip.html添加一個Zip擴展方法,因爲我使用的是.NET 3.5(我沒有指定對不起)。我需要改變我的匹配,並可能有一個新的正則表達式來處理'Case Else',因爲它也出現了(我沒有在我的原始問題中提到過)。 – 2011-03-21 21:43:02

+0

@Sarah - 沒問題,開心幫忙':'''' – Kobi 2011-03-21 22:13:02