Как упорядочить содержимое текстового файла по номеру в строке?

Задача - дан текстовый файл, в нём содержится таблица вида:

    №           Серия       Наименование        Дополнение

    1           677492      12Тм 54             Допол

    1           Привет      76                  1з

    7           654         Это                 Твоё

    2           Тестовое    -=-=-=              СимволыИлиНет?

    0           Задание     ЉµЉ                 1787 - ?

    2147483747  Удачи       На полях            Правосудия

Вопрос - как упорядочить строки по номеру? Мой код:

public static void SortLines()
    {
        var str = File.ReadAllLines(@"E:\c#\ТестовоеЗадание\Задание3.txt");

        var headerFromTestFile = str.Take(2);

        var sortTXT = str.Skip(2).Take(str.Length - 2)
            .Where(x => x != "")
            //.GroupBy(x => int.Parse(x.Substring(0)))
            .GroupBy(x => int.Parse(x.Substring(x.IndexOf("\t\t", 9))))
            .OrderBy(g => g.Key)
            .SelectMany(g => g);
        var str2 = str.Skip(str.Length - 1);

        File.WriteAllLines(@"E:\c#\ТестовоеЗадание\Задание3.txt", headerFromTestFile.Concat(sortTXT).Concat(str2));
    }

При такой реализации ругается, что входная строка имела не верный формат.


Ответы (1 шт):

Автор решения: default locale

Вы выбираете подстроку (x.Substring(x.IndexOf("\t\t", 9))) от какого-то знака табуляции до конца строки, что несколько странно. Чтобы поиск работал через Substring нужно найти как начальную, так и конечную позиции номера в строке.

По-моему, номер проще искать с помощью регулярного выражения:

var sortTXT = str.Skip(2).Take(str.Length - 2)
            .Where(line => !string.IsNullOrWhiteSpace(line))
            .OrderBy(line => long.Parse(Regex.Match(line, "[0-9]+").Value));

Выражение [0-9]+ найдет первое число в строке.

Не совсем понял для чего используется str2. Если файл всегда заканчивается строкой с 2147483747, и бо́льшего номера в файле нет, то можно обойтись без нее. Если же там в конце какой-то подвал, то тогда для sortText нужно брать str.Length -3 строк.

Дополнение: если нужно после каждой строки оставлять пустую строку, то можно добавить к строкам знак переноса после сортировки:

var sortTXT = str.Skip(2).Take(str.Length - 2)
            .Where(line => !string.IsNullOrWhiteSpace(line))
            .OrderBy(line => long.Parse(Regex.Match(line, "[0-9]+").Value))
            .Select(line => line+Environment.NewLine);
→ Ссылка