Как удалить пустые строки из форматированной строки

Как удалить пустые строки в строке на С#?

Я создаю некоторые текстовые файлы на С# (Windows Forms), и по какой-то причине есть пустые строки. Как удалить их после создания строки (используя StringBuilder и TextWrite).

Пример текстового файла:

THIS IS A LINE



THIS IS ANOTHER LINE AFTER SOME EMPTY LINES!

person Saeid Yazdani    schedule 04.10.2011    source источник
comment
Удаление строк после генерации действительно то, что вы хотите сделать? Я думаю, вы должны посмотреть, почему вы генерируете лишние строки. Если вы используете методы WriteLine(...), они напишут новую строку за вас. Методы Write(...) не записывают новую последовательность строк.   -  person Mesh    schedule 04.10.2011
comment
Ну, это не моя вина, я извлекаю текст из некоторых текстовых файлов, и в этом проблема!   -  person Saeid Yazdani    schedule 04.10.2011
comment
stackoverflow.com/questions/4973524/   -  person Allen    schedule 29.01.2015


Ответы (11)


Если вы также хотите удалить строки, содержащие только пробелы, используйте

resultString = Regex.Replace(subjectString, @"^\s+$[\r\n]*", string.Empty, RegexOptions.Multiline);

^\s+$ удалит все от первой пустой строки до последней (в непрерывном блоке пустых строк), включая строки, содержащие только табуляцию или пробелы.

Затем [\r\n]* удалит последний CRLF (или просто LF, что важно, потому что механизм регулярных выражений .NET сопоставляет $ между \r и \n, как ни странно).

person Tim Pietzcker    schedule 04.10.2011
comment
Это почти работает, однако у меня есть одна проблема: последняя строка пуста и не удаляется. Я плохо разбираюсь в регулярных выражениях, поэтому не знаю, почему? - person Robin Rye; 09.07.2012
comment
@RobinRye: это потому, что для соответствия требуется хотя бы один пробельный символ. Если вы измените \s+ на \s*, то он также должен удалить последнюю строку. - person Tim Pietzcker; 09.07.2012
comment
Спасибо, Тим, я тоже так думал, немного изучив Regex, но это не помогло. Изменено на \s*, но последняя строка осталась в результирующей строке. Я использовал str.Trim(), чтобы избавиться от него. - person Robin Rye; 09.07.2012
comment
Это также удаляет последнюю пустую строку: Regex.Replace(subjectString, @[\r\n]*^\s*$[\r\n]*, , RegexOptions.Multiline); - person Diana; 10.05.2016
comment
@Diana: Это может иметь побочный эффект. В некоторых случаях с помощью этого метода удаляется много символов новой строки. - person roland; 07.11.2016
comment
@RobinRye Использование str.Trim() удалит символы пробела и табуляции в начале первой строки текста. Вместо этого вы можете использовать str.TrimEnd(). Если вы также хотите сохранить пробелы/табуляцию в конце последней строки текста, используйте str.TrimEnd('\r','\n'). - person Collin K; 12.02.2018
comment
@RicardoFontana: Можете ли вы уточнить, почему это не работает? Этот ответ довольно специфичен для регулярных выражений .NET - как вы используете это в Unix? - person Tim Pietzcker; 25.06.2018
comment
@TimPietzcker Я пишу тестовый метод [Theory] [InlineData("\nText sample")] // Windows break line [InlineData("\r\nText sample")] // Unix break line public void RemoveBlankLinesInLinuxAndWindows(string text) { resultString = Regex.Replace(text, @"^\s+$[\r\n]*", string.Empty, RegexOptions.Multiline); Assert.Equal("Text sample", resultString); } - person Ricardo Fontana; 25.06.2018
comment
@TimPietzcker измените регулярное выражение, например, oobe @"^\s*$\n|\r", начните работать. - person Ricardo Fontana; 25.06.2018

Тим Пицкер - это не работает для меня. Мне нужно немного измениться, но спасибо!

Эххх С# Regex. Мне пришлось снова изменить его, но это работает хорошо:

private string RemoveEmptyLines(string lines)
{
  return Regex.Replace(lines, @"^\s*$\n|\r", string.Empty, RegexOptions.Multiline).TrimEnd();
}

Пример: http://regex101.com/r/vE5mP1/2

person oobe    schedule 23.07.2014

Вы можете попробовать String.Replace("\n\n", "\n");

person user807566    schedule 04.10.2011
comment
хорошо, спасибо, но это не общее решение, не будет включать вкладки, пробелы и тому подобное - person Saeid Yazdani; 04.10.2011
comment
В вашем вопросе об этом ничего не сказано. На самом деле вы специально сказали пустые строки. - person user807566; 04.10.2011
comment
Я также прикрепил Trim(). Но все же в случаях \n\n\n это не сработает. - person HappyNomad; 06.10.2013
comment
Ну, на самом деле это не разрешает все пустые строки. Я столкнулся с ситуацией, когда у меня есть переменное количество концевых линий, сходящихся вместе. Так что в этом случае нам нужно несколько раз перебрать текст. - person Arsinclair; 21.02.2017

Попробуй это

Regex.Replace(subjectString, @"^\r?\n?$", "", RegexOptions.Multiline);
person Narendra Yadala    schedule 04.10.2011

Ни один из упомянутых здесь методов не помог мне полностью, но я нашел обходной путь.

  1. Разделить текст на строки - набор строк (с пустыми строками или без них, а также Обрезать() каждую строку).

  2. Добавьте эти строки в многострочную строку.

     public static IEnumerable<string> SplitToLines(this string inputText, bool removeEmptyLines = true)
     {
         if (inputText == null)
         {
             yield break;
         }
    
         using (StringReader reader = new StringReader(inputText))
         {
             string line;
             while ((line = reader.ReadLine()) != null)
             {
                 if (removeEmptyLines && !string.IsNullOrWhiteSpace(line))
                     yield return line.Trim();
                 else
                     yield return line.Trim();
             }
         }
     }
    
     public static string ToMultilineText(this string text)
     {
         var lines = text.SplitToLines();
    
         return string.Join(Environment.NewLine, lines);
     }
    
person scarybook    schedule 22.07.2020

На основе кода Евгения Соболева, Я написал этот метод расширения, который также обрезает последний (устаревший) разрыв строки с помощью TrimEnd(TrimNewLineChars):

public static class StringExtensions
{
    private static readonly char[] TrimNewLineChars = Environment.NewLine.ToCharArray();

    public static string RemoveEmptyLines(this string str)
    {
        if (str == null)
        {
            return null;
        }

        var lines = str.Split(TrimNewLineChars, StringSplitOptions.RemoveEmptyEntries);

        var stringBuilder = new StringBuilder(str.Length);

        foreach (var line in lines)
        {
            stringBuilder.AppendLine(line);
        }

        return stringBuilder.ToString().TrimEnd(TrimNewLineChars);
    }
}
person thomasgalliker    schedule 25.05.2019
comment
Ваше расширение работает только в том случае, если рассматриваемая строка происходит из той же системы. если он передается между системами, такими как lnux, web, в windows, он вообще не будет работать. Рассмотрите возможность изменения TrimNewLineChars на фактический массив - person AaA; 26.05.2019
comment
Я не знаю, что вы имеете в виду. Можете ли вы опубликовать пример строки, где она не будет работать, и я напишу с ней модульный тест. Спасибо. - person thomasgalliker; 27.05.2019
comment
Попробуйте использовать его для текстовых файлов, в которых последовательность конца строки представляет собой CR + LF ( Windows), LF (Linux) и Mac (классический, до Max OS X) (CR). CR = ASCII 13. [LF](LF) = ASCII 10. - person Peter Mortensen; 17.05.2021
comment
Именно на это и намекает AaA. Environment.NewLine работает только в том случае, если файл был создан с последовательностью конца строки по умолчанию для текущей системы. Большинство продвинутых текстовых редакторов могут обрабатывать/устанавливать/сохранять в форматах (в Visual Studio Code это с помощью несколько скрытой функции, которую вы можете нажмите отображаемую настройку (например, LF) для данного файл в правом нижнем углу и изменить его прямо там). - person Peter Mortensen; 17.05.2021
comment
Пожалуйста, внимательно прочитайте вопрос, прежде чем голосовать против всех. - person thomasgalliker; 18.05.2021

Я пробовал предыдущие ответы, но некоторые из них с регулярным выражением работают неправильно.

Если вы используете регулярное выражение для поиска пустых строк, вы не можете использовать его для удаления.

Потому что он удалит разрывные линии непустых строк.

Вы должны использовать группы регулярных выражений для этой замены.

Некоторые другие ответы здесь без регулярных выражений могут иметь проблемы с производительностью.

    private string remove_empty_lines(string text) {
        StringBuilder text_sb = new StringBuilder(text);
        Regex rg_spaces = new Regex(@"(\r\n|\r|\n)([\s]+\r\n|[\s]+\r|[\s]+\n)");
        Match m = rg_spaces.Match(text_sb.ToString());
        while (m.Success) {
            text_sb = text_sb.Replace(m.Groups[2].Value, "");
            m = rg_spaces.Match(text_sb.ToString());
        }
        return text_sb.ToString().Trim();
    }
person antoine    schedule 05.12.2019

Этот шаблон идеально подходит для удаления пустых строк и строк, содержащих только пробелы и/или табуляции.

s = Regex.Replace(s, "^\s*(\r\n|\Z)", "", RegexOptions.Multiline)
person Ivan Ferrer Villa    schedule 30.09.2016

Я нашел простой ответ на эту проблему:

YourradTextBox.Lines = YourradTextBox.Lines.Where(p => p.Length > 0).ToArray();

Адаптировано из Marco Minerva [MCPD] на Удалить строки из многострочного текстового поля, если оно содержит определенную строку - C#

person Scooter    schedule 11.03.2018

person    schedule
comment
AppendLine добавляет пустую строку в конец возвращаемой строки. - person thomasgalliker; 25.05.2019
comment
@thomasgalliker, это намерение. split удаляет новую строку с конца строки, поэтому вам нужно будет добавить ее обратно, иначе все ваши строки будут искажены в одну строку! Единственная проблема заключается в том, что Environment.NewLine является строкой и не может поместиться в массив символов. - person AaA; 26.05.2019

person    schedule
comment
пожалуйста, добавьте описание - person zohar; 16.08.2015
comment
У вас проблема с производительностью. попробуйте протестировать свой метод со строкой, содержащей 1 миллион \n внутри. подумайте об использовании StringBuilder вместо +String И я думаю, что вызов вашей функции RemoveEmptyLines имеет больше смысла. - person AaA; 26.05.2019
comment
Объяснение было бы в порядке. - person Peter Mortensen; 17.05.2021