parsing VB6 code in .NET

后端 未结 1 965
隐瞒了意图╮
隐瞒了意图╮ 2021-01-03 02:25

I have a WPF project written in C#, and in order to get some information about an external dependency, I need to parse a VB6 script. The script\'s location changes and its

相关标签:
1条回答
  • 2021-01-03 03:01

    You can parse it in a few steps. Please note the regex misses strings and comments, so use with care.

    First, we'll use a helper class for the Fields("Target").List = Lists("Value") lines:

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

    Out patterns:

    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+)*
    ";
    

    Next, we can try to parse the text in two passes (the code is a little ugly, by the way, but fairly basic):

    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);
    }
    

    Now you have a dictionary with all data. For example:

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

    Here's a working example: https://gist.github.com/880148

    0 讨论(0)
提交回复
热议问题