парсинг кода VB6 в .NET - PullRequest
5 голосов
/ 21 марта 2011

У меня есть проект WPF, написанный на C #, и чтобы получить некоторую информацию о внешней зависимости, мне нужно проанализировать скрипт VB6.Меняется местоположение скрипта и его содержимое, но основной код, который меня интересует, будет иметь формат:

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

Мне нужно извлечь из этого то, что, когда поле 'blah' установлено в 'какое-то значение », список для поля« прочее бла »меняется на список« имя списка ».Я пробовал поискать в Google парсер VB6, написанный как библиотеку .NET, но пока ничего не нашел.С риском получить ответ типа этот , я должен просто использовать регулярные выражения, чтобы найти код, подобный этому, в скрипте VB6, и извлечь нужные мне данные?Код находится в подпрограмме, так что я не могу передать «бла», «какое-то значение» и получить «другое бла», «имя списка».Я не контролирую содержимое этого скрипта VB6.

1 Ответ

4 голосов
/ 21 марта 2011

Вы можете разобрать его за несколько шагов.Обратите внимание, что регулярное выражение пропускает строки и комментарии, поэтому используйте их осторожно.

Сначала мы будем использовать вспомогательный класс для строк Fields("Target").List = Lists("Value"):

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

Шаблоны Out:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...