问题描述
我有一个用 C# 编写的 WPF 项目,为了获取有关外部依赖项的一些信息,我需要解析一个 VB6 脚本.脚本的位置发生了变化,其内容也发生了一些变化,但我感兴趣的主要代码将是以下格式:
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 content changes some, but the main code I'm interested in will be of the format:
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 解析器,但还没有找到任何东西.冒着得到这个答案的风险,我应该只使用正则表达式在VB6脚本中找到这样的代码,然后提取我需要的数据吗?该代码在子例程中找到,因此我无法传入blah"、some value"并取回other blah"、列表名称".我无法控制这个 VB6 脚本的内容.
I need to extract from this that when field 'blah' is set to 'some value', the list for field 'other blah' changes to list 'a list name'. I tried Googling around for a VB6 parser written as a .NET library but haven't found anything yet. At the risk of getting an answer like this one, should I just use regular expressions to find the code like this in the VB6 script, and extract the data I need? The code is found in a subroutine such that I can't pass in 'blah', 'some value' and get back 'other blah', 'a list name'. I have no control over the contents of this VB6 script.
推荐答案
你可以分几步解析它.请注意,正则表达式会遗漏字符串和注释,因此请谨慎使用.
You can parse it in a few steps. Please note the regex misses strings and comments, so use with care.
首先,我们将为 Fields("Target").List = Lists("Value")
行使用帮助类:
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; }
}
输出模式:
string patternSelectCase = @"
Selects+Cases+Fields(""(?<CaseField>[ws]+)"").Value
(?<Cases>.*?)
Ends+Select
";
string patternCase = @"
Cases+""(?<Case>[ws]+)""s+
(?:Fields(""(?<Target>[ws]+)"").Lists*=s*Lists(""(?<Value>[ws]+)"")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;
这是一个工作示例:https://gist.github.com/880148
这篇关于在 .NET 中解析 VB6 代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!