Який найпростіший спосіб у C # обрізати новий рядок із рядка?


115

Я хочу переконатися, що _content не закінчується символом NewLine:

_content = sb.ToString().Trim(new char[] { Environment.NewLine });

але вищевказаний код не працює, оскільки, здається, у Trim немає перевантаженого параметра для колекції рядків, лише символів.

Який найпростіший однолінійник для видалення Enivronment.Newline з кінця рядка?


4
btw, ви, мабуть, хочете TrimEnd
Marc Gravell

Відповіді:


260

Наступні роботи для мене.

sb.ToString().TrimEnd( '\r', '\n' );

або

sb.ToString().TrimEnd( Environment.NewLine.ToCharArray());

дуже лаконічно і займається питанням \ r \ n, приємно
Едуард Тангуай

1
Хоча обрізка БУДЬ-якої комбінації символів, що складають нову лінійку (графіки), вирішує основну проблему та дух питання, вона також залишає потенціал для небажаної функціональності в загальному розумінні. У сенаріо для обробки файлів я міг побачити необхідність залишити перший \ n недоторканим у рядку HeresALineForUnixToBeFedFromWindows \ n \ r \ n. Хоча більш багатослівна, відповідь Джона Скіта, мабуть, найкраща, а ReadLine Скотта Вайнштейна також більш "точний" (хоча, можливо, з трохи більше накладних витрат)
b_levitt

26
TrimEnd () вже виконує роботу без будь-яких параметрів! msdn.microsoft.com/de-de/library/… та msdn.microsoft.com/de-de/library/…
Маркус

3
@Markus Спасибі Я знайшов це, тому що я не хочу такої поведінки, але відчував це. Я був під враженням \ n це не білий простір, але це є .TrimEnd і .Trim очистити всі символи білого простору споконвічно
Девід Керіган


14

Як щодо:

public static string TrimNewLines(string text)
{
    while (text.EndsWith(Environment.NewLine))
    {
        text = text.Substring(0, text.Length - Environment.NewLine.Length);
    }
    return text;
}

Це дещо неефективно, якщо є кілька нових рядків, але це спрацює.

З іншого боку , якщо ви не заперечуєте , то кадрування (скажімо) "\r\r\r\r"або , "\n\n\n\n"а не просто "\r\n\r\n\r\n":

// No need to create a new array each time
private static readonly char[] NewLineChars = Environment.NewLine.ToCharArray();

public static string TrimNewLines(string text)
{
    return text.TrimEnd(NewLineChars);
}

1
Мабуть, найточніше рішення, але не однолінійний :-)
удар

9

Використовуйте рамки. Метод ReadLine () повинен сказати наступне:

Рядок визначається як послідовність символів, за якою слід подавати рядок ("\ n"), повернення каретки ("\ r") або повернення каретки негайно, за яким слід подавати рядок ("\ r \ n"). Рядок, який повертається, не містить завершального повернення каретки або каналу рядка.

Тож наступне зробить трюк

_content = new StringReader(sb.ToString()).ReadLine();

1
Елегантний так, але нелегкий для розуміння для інших, хто читає цей рядок. Потрібні пояснювальні коментарі (в тому ж рядку, звичайно, щоб залишатися одноколірним :))
gumo

1
Не відбувається, коли рядок містить більше одного рядка, і ви хочете видалити лише останній порожній рядок.
Флоріан Бергер

6

А як на рахунок

_content = sb.ToString().Trim(Environment.NewLine.ToCharArray());

Це не робить зовсім те ж саме - це буде обрізати «а \ п \ п \ п \ п \ п», наприклад, навіть якщо Environment.NewLine є CRLF
Marc Gravell

1
Задекларуйте це як особливість :-) Мені подобається рішення.
Стефан Штейнеггер

5
_content = sb.TrimEnd(Environment.NewLine.ToCharArray());

Це, звичайно, видалить "\ r \ r \ r \ r", а також "\ n \ n \ n \ n" та інші комбінації. А в "середовищі", де NewLine відрізняється від "\ n \ r", ви можете отримати дивні поведінки :-)

Але якщо ви можете жити з цим, то я вірю, що це найефективніший спосіб видалення нових символів рядка в кінці рядка.


3

Як щодо:

string text = sb.ToString().TrimEnd(null)

Це потягне за собою всі символи пробілу з кінця рядка - лише проблема, якщо ви хочете зберегти не-новий рядок пробілів.


1

Дещо невідповідь, але найпростіший спосіб обрізати новий рядок від рядка - це не мати першої рядки на рядку в першу чергу, переконавшись, що його ніколи не бачать ваш власний код. Тобто, використовуючи нативні функції, які видаляють новий рядок. Багато методів потоку та файлів / io не включатимуть новий рядок, якщо ви запитаєте вихідний рядок за рядком, хоча, можливо, буде потрібно щось обгортати в System.IO.BufferedStream.

Такі речі System.IO.File.ReadAllLinesможна використовувати замість System.IO.File.ReadAllTextбільшої частини часу та ReadLineвикористовувати їх замість Readодного разу, коли ви працюєте з правильним типом потоку (наприклад BufferedStream).


0

Як зазначив Маркус, зараз TrimEnd виконує цю роботу. Мені потрібно було отримати канали ліній та пробіл з обох кінців рядка в середовищі Windows Phone 7.8. Переслідувавши різні складніші варіанти, мою проблему було вирішено лише за допомогою Trim () - добре пройшов наступні тести

   [TestMethod]
    [Description("TrimNewLines tests")]
    public void Test_TrimNewLines()
    {
        Test_TrimNewLines_runTest("\n\r     testi    \n\r", "testi");
        Test_TrimNewLines_runTest("\r     testi    \r", "testi");
        Test_TrimNewLines_runTest("\n     testi    \n", "testi");
        Test_TrimNewLines_runTest("\r\r\r\r\n\r     testi   \r\r\r\r \n\r", "testi");
        Test_TrimNewLines_runTest("\n\r  \n\n\n\n   testi äål.,    \n\r", "testi äål.,");
        Test_TrimNewLines_runTest("\n\n\n\n     testi  ja testi  \n\r\n\n\n\n", "testi  ja testi");
        Test_TrimNewLines_runTest("", "");
        Test_TrimNewLines_runTest("\n\r\n\n\r\n", "");
        Test_TrimNewLines_runTest("\n\r \n\n \n\n", "");
    }

    private static void Test_TrimNewLines_runTest(string _before, string _expected)
    {
        string _response = _before.Trim();
        Assert.IsTrue(_expected == _response, "string '" + _before + "' was translated to '" + _response + "' - should have been '" + _expected + "'");
    }

-2

Мені довелося видаляти нові рядки з усього тексту. Тому я використав:

            while (text.Contains(Environment.NewLine))
            {
                text = text.Substring(0, text.Length - Environment.NewLine.Length);
            }

1
Це буде катастрофою, якщо текст містить NewLine (s), які ще не закінчуються.
Штефан Бергфельдт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.