【问题标题】:parsing VB6 code in .NET在 .NET 中解析 VB6 代码
【发布时间】:2011-07-19 22:04:17
【问题描述】:

我有一个用 C# 编写的 WPF 项目,为了获取有关外部依赖项的一些信息,我需要解析一个 VB6 脚本。脚本的位置发生了变化,其内容也发生了一些变化,但我感兴趣的主要代码将是以下格式:

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

我需要从中提取当字段 'blah' 设置为 'some value' 时,字段 'other blah' 的列表更改为列表 'a list name'。我试着用谷歌搜索一个 .NET 库的 VB6 解析器,但还没有找到任何东西。冒着得到this one之类的答案的风险,我是否应该只使用正则表达式在VB6脚本中找到这样的代码,并提取我需要的数据?该代码在子例程中找到,因此我无法传入“blah”、“some value”并返回“other blah”、“列表名称”。我无法控制这个 VB6 脚本的内容。

【问题讨论】:

标签: .net regex parsing vb6


【解决方案1】:

您可以通过几个步骤解析它。请注意,正则表达式会遗漏字符串和 cmets,因此请谨慎使用。

首先,我们将为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

【讨论】:

  • 谢谢!这些正则表达式很棒,而且比我想出的更彻底。我必须从 weblogs.thinktecture.com/cnagel/2010/02/… 添加一个 Zip 扩展方法,因为我使用的是 .NET 3.5(我没有指定,抱歉)。我需要改变我的匹配,并且可能有一个新的正则表达式来处理Case Else,因为它也会出现(我在最初的问题中没有提到)。
  • @Sarah - 没问题,乐于帮助:)
猜你喜欢
  • 2012-09-29
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多