2011-03-21 25 views
5

Tengo un proyecto WPF escrito en C#, y para obtener información sobre una dependencia externa, necesito analizar un script VB6. cambios de ubicación del guión y su contenido cambia algunos, pero el código principal que estoy interesado serán del formato:analizando el código VB6 en .NET

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

necesito para extraer de esto que cuando el campo 'bla' está en 'un cierto valor ', la lista para el campo' otro bla 'cambia a la lista' un nombre de lista '. Intenté buscar en Google un analizador VB6 escrito como biblioteca .NET pero aún no he encontrado nada. A riesgo de obtener una respuesta como this one, ¿debería usar expresiones regulares para encontrar el código como este en el script VB6 y extraer los datos que necesito? El código se encuentra en una subrutina tal que no puedo pasar 'blah', 'algún valor' y recuperar 'otro bla', 'un nombre de lista'. No tengo control sobre el contenido de este script VB6.

+0

Véase también [esta cuestión] (http://stackoverflow.com/questions/1129149/visual-basic-6-0-language-syntax) . Por ejemplo, hay una [gramática para VBScript] (http://stackoverflow.com/questions/1129149/visual-basic-6-0-language-syntax/1129425#1129425), y un comercializador de terceros [analizador VB6] (http://stackoverflow.com/questions/1129149/visual-basic-6-0-language-syntax/1129163#1129163). – MarkJ

Respuesta

4

Puede analizarlo en unos pocos pasos. Tenga en cuenta que la expresión regular omite cadenas y comentarios, por lo que debe usarse con cuidado.

En primer lugar, vamos a utilizar una clase de ayuda para las líneas Fields("Target").List = Lists("Value"):

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

fuera patrones:

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

A continuación, podemos tratar de analizar el texto en dos pasadas (el código es un poco feo, por cierto, pero bastante básico):

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

Ahora usted tiene un diccionario con todos los datos . Por ejemplo:

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

Aquí está un ejemplo de trabajo: https://gist.github.com/880148

+0

¡Gracias! Estas expresiones regulares son geniales y más exhaustivas de lo que se me ocurrió. Tuve que agregar un método de extensión Zip desde http://weblogs.thinktecture.com/cnagel/2010/02/linq-with-net-4-zip.html porque estoy usando .NET 3.5 (no especifiqué eso, lo siento). Tendré que modificar mi correspondencia y probablemente tenga una nueva expresión regular para manejar 'Case Else', ya que eso también aparece (no lo mencioné en mi pregunta original). –

+0

@Sarah - No hay problema, feliz de ayudar ':)' – Kobi