bmw318mt Ответов: 1

Разбор отформатированного текстового файла


У меня есть текстовый файл, который я получаю его содержимое через форматированную строку, которая выглядит следующим образом:
Таблица OperatorPoints \Р\nHEADING\Р\Имя_экземпляра nDGName OP1_X OP1_Y OP2_X OP2_Y\Р\nDATA\Р\Ноттингем, ng1[1,1] П1[1,1] 251.8419 -804.6282 768.8362 -290.5563\Р\Ноттингем, ng1[1,1] умереть[1,1] 357.8950 -714.6857 652.0683 -395.6490\Р\усилиям nend смогла
Форматирование в текстовом файле выглядит следующим образом
TABLE OperatorPoints 
HEADING
DGName                  InstanceName        OP1_X        OP1_Y        OP2_X        OP2_Y
DATA
G1[1,1]                      L1[1,1]     251.8419    -804.6282     768.8362    -290.5563
G1[1,1]                   valve[1,1]     357.8950    -714.6857     652.0683    -395.6490
END

Содержимое мое различается, однако заголовки (DGName, InstanceName и т. д.) всегда одинаковы.

Меня интересуют только значения, и мне нужно уметь читать каждое значение и хранить его в объекте класса. В качестве значений содержимого мой пример vary вместо G1[1,1] может быть более длинный текст, и поэтому для других ячеек. Там также могут отсутствовать ячейки, например 251.8419 в OP1_X отсутствует. То,что я имею в виду, - это иметь словарь <string, int>, где я помещаю заголовки и ширину "ячейки", чтобы затем прочитать значения, основанные на точном местоположении.

Что я уже пробовал:

Прямо сейчас я отделяю каждую строчку
string[] result = myString.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
затем используйте foreach для каждой строки. Но недостаток если это пропущенное значение все остальные значения для этой строки будут двигаться влево таким образом я получу пропущенное значение в последнем столбце

Richard MacCutchan

Не удаляйте пустые записи.

1 Ответов

Рейтинг:
0

RmcbainTheThird

Если можно удалить строки ,содержащие точки оператора таблицы,заголовок, данные и конец
вы можете передать поток файлов в этот класс. Я использовал его, чтобы взять CSV-файл и вернуть таблицу данных. Глядя на пример файла, я предполагаю, что данные разделены табуляцией. В этом случае вам нужно будет изменить класс, чтобы использовать tab для разделителя вместо запятых.
удачи

public class CsvParser
    {
        public static DataTable Parse(string data, bool headers)
        {
            return Parse(new StringReader(data), headers);
        }

        public static DataTable Parse(string data)
        {
            return Parse(new StringReader(data));
        }

        public static DataTable Parse(TextReader stream)
        {
            return Parse(stream, false);
        }

        public static DataTable Parse(TextReader stream, bool headers)
        {
            DataTable table = new DataTable();
            CsvStream csv = new CsvStream(stream);
            string[] row = csv.GetNextRow();
            if (row == null)
                return null;
            if (headers)
            {
                foreach (string header in row)
                {
                    if (header != null && header.Length > 0 && !table.Columns.Contains(header))
                        table.Columns.Add(header, typeof(string));
                    else
                        table.Columns.Add(GetNextColumnHeader(table), typeof(string));
                }
                row = csv.GetNextRow();
            }
            while (row != null)
            {
                while (row.Length > table.Columns.Count)
                    table.Columns.Add(GetNextColumnHeader(table), typeof(string));
                table.Rows.Add(row);
                row = csv.GetNextRow();
            }
            return table;
        }

        private static string GetNextColumnHeader(DataTable table)
        {
            int c = 1;
            while (true)
            {
                string h = "Column" + c++;
                if (!table.Columns.Contains(h))
                    return h;
            }
        }

        private class CsvStream
        {
            private TextReader stream;

            public CsvStream(TextReader s)
            {
                stream = s;
            }

            public string[] GetNextRow()
            {
                ArrayList row = new ArrayList();
                while (true)
                {
                    string item = GetNextItem();
                    if (item == null)
                        return row.Count == 0 ? null : (string[])row.ToArray(typeof(string));
                    row.Add(item);
                }
            }

            private bool EOS = false;
            private bool EOL = false;

            private string GetNextItem()
            {
                if (EOL)
                {
                    // previous item was last in line, start new line
                    EOL = false;
                    return null;
                }

                bool quoted = false;
                bool predata = true;
                bool postdata = false;
                StringBuilder item = new StringBuilder();

                while (true)
                {
                    char c = GetNextChar(true);
                    if (EOS)
                        return item.Length > 0 ? item.ToString() : null;

                    if ((postdata || !quoted) && c == ',')
                        // end of item, return
                        return item.ToString();

                    if ((predata || postdata || !quoted) && (c == '\x0A' || c == '\x0D'))
                    {
                        // we are at the end of the line, eat newline characters and exit
                        EOL = true;
                        if (c == '\x0D' && GetNextChar(false) == '\x0A')
                            // new line sequence is 0D0A
                            GetNextChar(true);
                        return item.ToString();
                    }

                    if (predata && c == ' ')
                        // whitespace preceeding data, discard
                        continue;

                    if (predata && c == '"')
                    {
                        // quoted data is starting
                        quoted = true;
                        predata = false;
                        continue;
                    }

                    if (predata)
                    {
                        // data is starting without quotes
                        predata = false;
                        item.Append(c);
                        continue;
                    }

                    if (c == '"' && quoted)
                    {
                        if (GetNextChar(false) == '"')
                            // double quotes within quoted string means add a quote       
                            item.Append(GetNextChar(true));
                        else
                            // end-quote reached
                            postdata = true;
                        continue;
                    }

                    // all cases covered, character must be data
                    item.Append(c);
                }
            }

            private char[] buffer = new char[4096];
            private int pos = 0;
            private int length = 0;

            private char GetNextChar(bool eat)
            {
                if (pos >= length)
                {
                    length = stream.ReadBlock(buffer, 0, buffer.Length);
                    if (length == 0)
                    {
                        EOS = true;
                        return '\0';
                    }
                    pos = 0;
                }
                if (eat)
                    return buffer[pos++];
                else
                    return buffer[pos];
            }
        }
    }