Используйте алгоритм, подобный этому:
Обрабатывает каждый символ каждой строки по одному.
Подсчитайте все, что вы найдете.
Если число «s нечетное, вы знаете, что вам нужно продолжать читать текущее поле, пока вы не нажмете другое».
Если число "s" четное, вы знаете, что как только вы попадаете в пробел, вы переходите к следующему полю.
Что-то вроде (могут быть ошибки - я только что записал это на макушке):
StringBuilder field = new StringBuilder();
int quoteCount = 0;
foreach (char c in line)
{
if (c == '"')
{
quotCount++;
continue;
}
if (quoteCount % 2 = 0)
{
if (c == ' ')
{
yield return field.ToString();
field.Length = 0;
}
else
{
field.Append(c);
}
}
else
{
field.Append(c);
}
}
EDIT:
Вот хакерский пример, который работает для вашего примера - метод GetFields нуждается в некотором рефакторинге , и это далеко от качества всего, что я бы добавил в свой код, но основной принцип есть. *
class Program
{
static void Main(string[] args)
{
var records = ReadFile(@"D:\x.txt");
foreach (var record in records)
{
foreach (var field in record)
{
Console.Write(field + " | ");
}
Console.WriteLine();
}
Console.ReadKey();
}
static IEnumerable<IEnumerable<String>> ReadFile(String file)
{
using (var reader = new StreamReader(file))
{
// Ignore column titles line.
reader.ReadLine();
while (!reader.EndOfStream)
{
yield return GetFields(reader.ReadLine());
}
}
}
static IEnumerable<String> GetFields(String line)
{
Int32 quoteCount = 0;
StringBuilder field = new StringBuilder();
foreach (var c in line)
{
if (c == '"')
{
quoteCount++;
continue;
}
if (quoteCount % 2 == 0)
{
if (c == ' ')
{
if (field.Length > 0)
{
yield return field.ToString();
field.Length = 0;
}
}
else
{
field.Append(c);
}
}
else
{
field.Append(c);
}
}
yield return field.ToString();
}
}