Самый простой способ разбить строку на новые строки в .NET? - PullRequest
719 голосов
/ 10 октября 2009

Мне нужно разбить строку на новые строки в .NET, и единственный известный мне способ разбить строки - это метод Split . Однако это не позволит мне (легко) разбить на новую строку, так как лучше это сделать?

Ответы [ 15 ]

1269 голосов
/ 10 октября 2009

Чтобы разбить строку, вам нужно использовать перегрузку, которая принимает массив строк:

string[] lines = theText.Split(
    new[] { Environment.NewLine },
    StringSplitOptions.None
);

Edit:
Если вы хотите обрабатывать различные типы разрывов строк в тексте, вы можете использовать возможность сопоставления нескольких строк. Это правильно разделит любой тип перевода строки и сохранит пустые строки и интервалы в тексте:

string[] lines = theText.Split(
    new[] { "\r\n", "\r", "\n" },
    StringSplitOptions.None
);
99 голосов
/ 14 ноября 2012

Как насчет использования StringReader?

using (System.IO.StringReader reader = new System.IO.StringReader(input)) {
    string line = reader.ReadLine();
}
43 голосов
/ 10 октября 2009

Вы должны быть в состоянии довольно легко разбить вашу строку, например:

aString.Split(Environment.NewLine.ToCharArray());
24 голосов
/ 01 мая 2014

Старайтесь избегать использования string.Split для общего решения, потому что вы будете использовать больше памяти везде, где вы используете функцию - исходную строку и разделенную копию, как в памяти. Поверьте мне, что это может быть одной из самых серьезных проблем, когда вы начинаете масштабирование - запустите 32-разрядное приложение пакетной обработки, обрабатывающее документы объемом 100 МБ, и вы получите 8 одновременных потоков. Не то чтобы я был там раньше ...

Вместо этого используйте такой итератор;

    public static IEnumerable<string> SplitToLines(this string input)
    {
        if (input == null)
        {
            yield break;
        }

        using (System.IO.StringReader reader = new System.IO.StringReader(input))
        {
            string line;
            while( (line = reader.ReadLine()) != null)
            {
                yield return line;
            }
        }
    }

Это позволит вам сделать более эффективный цикл памяти вокруг ваших данных;

foreach(var line in document.SplitToLines()) 
{
    // one line at a time...
}

Конечно, если вы хотите все это в памяти, вы можете сделать это;

var allTheLines = document.SplitToLines.ToArray();
23 голосов
/ 02 июня 2011

На основании ответа Гуффы в классе расширения используйте:

public static string[] Lines(this string source) {
    return source.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
}
8 голосов
/ 04 октября 2012

Для строковой переменной s:

s.Split(new string[]{Environment.NewLine},StringSplitOptions.None)

Здесь используется определение концов строк в вашей среде. В Windows окончание строки - CR-LF (возврат каретки, перевод строки) или escape-символы C # \r\n.

Это надежное решение, потому что если вы рекомбинируете строки с String.Join, это будет равно вашей исходной строке:

var lines = s.Split(new string[]{Environment.NewLine},StringSplitOptions.None);
var reconstituted = String.Join(Environment.NewLine,lines);
Debug.Assert(s==reconstituted);

Что не делать:

  • Используйте StringSplitOptions.RemoveEmptyEntries, потому что это нарушит разметку, такую ​​как Markdown, где пустые строки имеют синтаксическое назначение.
  • Разделить на разделитель new char[]{Environment.NewLine}, потому что в Windows это создаст один пустой строковый элемент для каждой новой строки.
7 голосов
/ 10 января 2013

Regex также опция:

    private string[] SplitStringByLineFeed(string inpString)
    {
        string[] locResult = Regex.Split(inpString, "[\r\n]+");
        return locResult;
    }
6 голосов
/ 10 июля 2016

Я просто подумал, что добавлю свои два бита, потому что другие решения по этому вопросу не попадают в классификацию кода для повторного использования и не удобны.

Следующий блок кода расширяет объект string, чтобы он был доступен как естественный метод при работе со строками.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.Collections.ObjectModel;

namespace System
{
    public static class StringExtensions
    {
        public static string[] Split(this string s, string delimiter, StringSplitOptions options = StringSplitOptions.None)
        {
            return s.Split(new string[] { delimiter }, options);
        }
    }
}

Теперь вы можете использовать функцию .Split() из любой строки следующим образом:

string[] result;

// Pass a string, and the delimiter
result = string.Split("My simple string", " ");

// Split an existing string by delimiter only
string foo = "my - string - i - want - split";
result = foo.Split("-");

// You can even pass the split options parameter. When omitted it is
// set to StringSplitOptions.None
result = foo.Split("-", StringSplitOptions.RemoveEmptyEntries);

Чтобы разделить символ новой строки, просто передайте "\n" или "\r\n" в качестве параметра разделителя.

Комментарий: Было бы неплохо, если бы Microsoft реализовала эту перегрузку.

4 голосов
/ 14 мая 2013

В настоящее время я использую эту функцию (на основе других ответов) в VB.NET:

Private Shared Function SplitLines(text As String) As String()
    Return text.Split({Environment.NewLine, vbCrLf, vbLf}, StringSplitOptions.None)
End Function

Сначала он пытается разделить на новую строку платформы, а затем возвращается к каждой возможной новой строке.

Пока мне нужно было это только в одном классе. Если это изменится, я, вероятно, сделаю это Public и переместу его в служебный класс, и, возможно, даже сделаю его методом расширения.

Вот, как правильно соединить строки обратно:

Private Shared Function JoinLines(lines As IEnumerable(Of String)) As String
    Return String.Join(Environment.NewLine, lines)
End Function
2 голосов
/ 10 октября 2009

Ну, на самом деле разделение должно сделать:

//Constructing string...
StringBuilder sb = new StringBuilder();
sb.AppendLine("first line");
sb.AppendLine("second line");
sb.AppendLine("third line");
string s = sb.ToString();
Console.WriteLine(s);

//Splitting multiline string into separate lines
string[] splitted = s.Split(new string[] {System.Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries);

// Output (separate lines)
for( int i = 0; i < splitted.Count(); i++ )
{
    Console.WriteLine("{0}: {1}", i, splitted[i]);
}
...