2011-03-21 7 views
5

WPN 프로젝트를 C#으로 작성했으며 외부 종속성에 대한 정보를 얻기 위해 VB6 스크립트를 구문 분석해야합니다. 스크립트의 위치 변화와 그 내용 일부를 변경하지만 내가 관심이있는 주요 코드는 형식이 될 것입니다 :.NET에서 VB6 코드 구문 분석

나는이에서 추출하는 것이 필요
Select Case Fields("blah").Value 
    Case "Some value" 
     Fields("other blah").List = Lists("a list name") 
    ... 
End Select 

필드 'ㅋ'은 '어떤 값으로 설정되어있는 경우 '을 선택하면'기타 정보 '입력란의 목록이'목록 이름 '으로 변경됩니다. .NET 라이브러리로 작성된 VB6 파서에 대해 인터넷 검색을 시도했지만 아직 아무것도 찾지 못했습니다. this one과 같은 대답을 얻을 위험이 있으므로 VB6 스크립트에서 이와 같은 코드를 찾기 위해 정규 표현식을 사용해야하며 필요한 데이터를 추출해야합니까? 코드는 서브 루틴에서 발견되어 'ㅋ', '약간의 가치'를 전달할 수 없으며 '기타 ㅋ', '목록 이름'등으로 돌아갈 수 있습니다. 이 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

답변

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

감사! 이 정규 표현식은 제가 생각해 낸 것보다 훌륭하고 철저합니다. .NET 3.5를 사용하기 때문에 http://weblogs.thinktecture.com/cnagel/2010/02/linq-with-net-4-zip.html에서 Zip 확장 메서드를 추가해야했습니다 (지정하지 않았습니다). 죄송합니다.) 내 일치를 변경하고 아마도 Case Else를 처리 할 새로운 정규 표현식을 가질 필요가있을 것입니다. 왜냐하면 그 역시 나옵니다 (원래의 질문에서는 언급하지 않았습니다). –

+0

@Sarah - 문제 없으니 도와 드리겠습니다.':))' – Kobi