Final Edit: I was able to find the duplicate field in the ini file. Thanks for all your help!
I use regex to parse an ini file and LINQ to store it in a dictionary:
Data examples:
[WindowSettings]
Window X Pos = '0'
Window Y Pos = '0'
Window Maximized = 'false'
Window Name = 'Jabberwocky'
[Entrance]
Directory = 'C: \ Rosetta Stone \ Logs'
EDIT: here is the file actually causing the problem: http://pastebin.com/mQSrkrcP
EDIT2: I narrowed it down to the point of invoking the last section in the file: [list_first_nonprintable]
For some reason, one of the files that I parse with this throws this exception:
System.ArgumentException: An item with the same key has already been added.
Do I have any way to find out which key is causing the problem (so that I can fix the file), or just skip the key that causes this and continue parsing?
Here is the code:
try { // Read content of ini file. string data = System.IO.File.ReadAllText(project); // Create regular expression to parse ini file. string pattern = @"^((?:\[)(?<Section>[^\]]*)(?:\])(?:[\r\n]{0,}|\Z))((?!\[)(?<Key>[^=]*?)(?:=)(?<Value>[^\r\n]*)(?:[\r\n]{0,4}))*"; //pattern = @" //^ # Beginning of the line //((?:\[) # Section Start // (?<Section>[^\]]*) # Actual Section text into Section Group // (?:\]) # Section End then EOL/EOB // (?:[\r\n]{0,}|\Z)) # Match but don't capture the CRLF or EOB // ( # Begin capture groups (Key Value Pairs) // (?!\[) # Stop capture groups if a [ is found; new section // (?<Key>[^=]*?) # Any text before the =, matched few as possible // (?:=) # Get the = now // (?<Value>[^\r\n]*) # Get everything that is not an Line Changes // (?:[\r\n]{0,4}) # MBDC \r\n // )* # End Capture groups"; // Parse each file into a Dictionary. Dictionary<string, Dictionary<string, string>> iniFile = (from Match m in Regex.Matches(data, pattern, RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline) select new { Section = m.Groups["Section"].Value, kvps = (from cpKey in m.Groups["Key"].Captures.Cast<Capture>().Select((a, i) => new { a.Value, i }) join cpValue in m.Groups["Value"].Captures.Cast<Capture>().Select((b, i) => new { b.Value, i }) on cpKey.i equals cpValue.i select new KeyValuePair<string, string>(cpKey.Value, cpValue.Value)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value) }).ToDictionary(itm => itm.Section, itm => itm.kvps); return iniFile; } catch (ArgumentException ex) { System.Diagnostics.Debug.Write(ex.ToString()); return new Dictionary<string, Dictionary<string, string>>(); }
Thanks in advance.