public Table(string input, char fieldDelimiter, bool quotedFields, string filter) { Rows = new List <string>(); RowFields = new List <List <string> >(); var csvStringConverter = new CsvStringConverter(fieldDelimiter, quotedFields); var sentinelIndex = input.Length; var numFields = 0; var startIndex0 = 0; int startIndex1; var lineNo = 1; var regexFilter = new Regex(filter); // add data row by row to table do { var fields = new List <string>(); startIndex1 = csvStringConverter.ConvertCsv(input, startIndex0, sentinelIndex, fields); var row = input.Substring(startIndex0, startIndex1 - startIndex0); if (row.EndsWith("\n")) { row = row.Substring(0, row.Length - 1); } if (!regexFilter.IsMatch(row)) { // skip all input rows that do not match the input regex filter startIndex0 = startIndex1; ++lineNo; continue; } if (numFields == 0) { numFields = fields.Count; } if (fields.Count != numFields) { throw new Exception( $"Found {fields.Count} fields instead of {numFields} fields in line {lineNo + 1}"); } RowFields.Add(fields); //Rows.Add(input.Substring(startIndex0, startIndex1 - startIndex0)); Rows.Add(string.Join(fieldDelimiter.ToString(CultureInfo.InvariantCulture), fields)); // record without recordDelimiter startIndex0 = startIndex1; ++lineNo; // ReSharper disable once LoopVariableIsNeverChangedInsideLoop } while (sentinelIndex != startIndex1); }
public Table(string input, char fieldDelimiter, bool quotedFields, string filter) { Rows = new List<string>(); RowFields = new List<List<string>>(); var csvStringConverter = new CsvStringConverter(fieldDelimiter, quotedFields); var sentinelIndex = input.Length; var numFields = 0; var startIndex0 = 0; int startIndex1; var lineNo = 1; var regexFilter = new Regex(filter); // add data row by row to table do { var fields = new List<string>(); startIndex1 = csvStringConverter.ConvertCsv(input, startIndex0, sentinelIndex, fields); var row = input.Substring(startIndex0, startIndex1 - startIndex0); if (row.EndsWith("\n")) { row = row.Substring(0, row.Length - 1); } if (!regexFilter.IsMatch(row)) { // skip all input rows that do not match the input regex filter startIndex0 = startIndex1; ++lineNo; continue; } if (numFields == 0) { numFields = fields.Count; } if (fields.Count != numFields) throw new Exception( $"Found {fields.Count} fields instead of {numFields} fields in line {lineNo + 1}"); RowFields.Add(fields); //Rows.Add(input.Substring(startIndex0, startIndex1 - startIndex0)); Rows.Add(string.Join(fieldDelimiter.ToString(CultureInfo.InvariantCulture), fields)); // record without recordDelimiter startIndex0 = startIndex1; ++lineNo; // ReSharper disable once LoopVariableIsNeverChangedInsideLoop } while (sentinelIndex != startIndex1); }
public void ConvertCsvTest() { const string input = "Vorname;Nachname;PLZ;Stadt;Straße;Nr\n" + ";a;\"a;\";\"a\r\n" + "\"\"b\";;\"\"\r\n" + "Michael;Heitland;31139;\"Hildesheim\";Trillkestraße;5\r\n" + "Karl;Müller;12345;Karlsruhe;\"\";\n"; var expectedOutput = new[] { "Vorname", "Nachname", "PLZ", "Stadt", "Straße", "Nr", "", "a", "a;", "a\n\"b", "", "", "Michael", "Heitland", "31139", "Hildesheim", "Trillkestraße", "5", "Karl", "Müller", "12345", "Karlsruhe", "", "" }; var csvStringConverter = new CsvStringConverter(';', true); var startIndex = 0; var sentinelIndex = input.Length; var output = new List<string>(); // ReSharper disable once LoopVariableIsNeverChangedInsideLoop while (sentinelIndex != (startIndex = csvStringConverter.ConvertCsv(input, startIndex, sentinelIndex, output))) { Assert.Equal(0, output.Count % 6); // invalid no of fields? } for (var i = 0; i < output.Count; ++i) { var currentOutput = output[i]; var currentExpected = expectedOutput[i]; Assert.Equal(currentOutput, currentExpected); } }