Parsing di un file .ini in un solo statement
Questo post è un po' una prosecuzione del precedente, in cui ho dato una rapida occhiata alla possibilità di approcciarsi al paradigma funzionale con LINQ. Il codice che vi propongo di seguito è in grado di eseguire il parsing completo di un file di configurazione usando solo due variabili di appoggio e condensando tutta l'elaborazione in una cascata di metodi di estensione linq. Ogni funzione lavora sull'output della precedente e fornisce l'input alla successiva. In questi casi l'inferenza di tipo diventa un'alleata preziosa:
static void Main(string[] args)
{
if (args.Length < 2)
return;
String fileName = args[1];
Regex sectionRegex = new Regex(@"\[(?<Section>\w+)\]");
Regex fieldRegex = new Regex(@"(?<Field>\w+)\s*\=\s*(?<Value>.*)");
Match match;
String lastSection = "<No Section>";
var ini = File.ReadAllLines(fileName)
.Select (line => line.Contains(';') ?
line.Remove(line.IndexOf(';')) :
line)
.Select (line => line.Trim())
.Where (line => !String.IsNullOrEmpty(line))
.GroupBy(line => (match = sectionRegex.Match(line)).Success ?
lastSection = match.Groups["Section"].Value :
lastSection)
.Select (group => new
{
SectionName = group.Key,
Fields = group
.Select(line => (match = fieldRegex.Match(line)).Success ?
new { Name = match.Groups["Field"].Value,
Value = match.Groups["Value"].Value } :
null)
.Where(element => element != null)
});
foreach (var section in ini)
{
Console.WriteLine("Section: {0}", section.SectionName);
foreach (var field in section.Fields)
Console.WriteLine(" Field {0} = {1}", field.Name, field.Value);
}
}
Un'altra funzionalità che ho sfruttato pesantemente è una costante di tutti i linguaggi C-like dagli albori della programmazione letterale imperativa: il valore di ritorno dell'operatore di assegnazione. Notate come non sarebbe stato possibile definire la chiave di raggruppamento se l'assegnazione di lastSection non avesse di fatto restituito il nuovo valore della variabile e come sarebbe stato necessario usare dei metodi anonimi anziché delle espressioni lambda se non avessi potuto richiamare la proprietà Success dall'oggetto esposto dall'assegnazione della variabile match.
Leave a Reply
You must be logged in to post a comment.
