Мне нужно разбить строку на новые строки в .NET, и единственный известный мне способ разбить строки - это метод Split . Однако это не позволит мне (легко) разбить на новую строку, так каков наилучший способ сделать это?
Мне нужно разбить строку на новые строки в .NET, и единственный известный мне способ разбить строки - это метод Split . Однако это не позволит мне (легко) разбить на новую строку, так каков наилучший способ сделать это?
Ответы:
Чтобы разбить строку, вам нужно использовать перегрузку, которая принимает массив строк:
string[] lines = theText.Split(
new[] { Environment.NewLine },
StringSplitOptions.None
);
Редактировать:
Если вы хотите обрабатывать различные типы разрывов строк в тексте, вы можете использовать возможность сопоставлять более чем одну строку. Это правильно разделит любой тип разрыва строки и сохранит пустые строки и интервалы в тексте:
string[] lines = theText.Split(
new[] { "\r\n", "\r", "\n" },
StringSplitOptions.None
);
Environment.NewLine
свойство содержит новую строку по умолчанию для системы. Например, для системы Windows это будет "\r\n"
.
\n
оставляя \r
точку в конце каждой строки, а затем выводит строки \r\n
между ними.
\r
и \n
escape (среди прочих) имеют особое значение для компилятора C #. VB не имеет этих escape-последовательностей, поэтому вместо них используются эти константы.
Как насчет использования StringReader
?
using (System.IO.StringReader reader = new System.IO.StringReader(input)) {
string line = reader.ReadLine();
}
while
цикла, который должен быть добавлен к этому ответу.
Вы должны быть в состоянии разбить вашу строку довольно легко, например так:
aString.Split(Environment.NewLine.ToCharArray());
Старайтесь избегать использования string.Split для общего решения, потому что вы будете использовать больше памяти везде, где вы используете функцию - исходную строку и разделенную копию, как в памяти. Поверьте мне, что это может быть одной из самых серьезных проблем, когда вы начинаете масштабирование - запустите 32-разрядное приложение пакетной обработки, обрабатывающее документы объемом 100 МБ, и вы справитесь с восемью одновременными потоками. Не то чтобы я был там раньше ...
Вместо этого используйте такой итератор;
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();
blah.SplitToLines..
например document.SplitToLines...
?
this
формальные параметры, что делает его методом расширения.
Основываясь на ответе Гуффы, в классе расширения используйте:
public static string[] Lines(this string source) {
return source.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
}
Для строковой переменной 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 это создаст один пустой строковый элемент для каждой новой строки.Regex также вариант:
private string[] SplitStringByLineFeed(string inpString)
{
string[] locResult = Regex.Split(inpString, "[\r\n]+");
return locResult;
}
"\r?\n"
.
Я просто подумал, что добавлю свои два бита, потому что другие решения по этому вопросу не попадают в классификацию кода для повторного использования и не удобны.
Следующий блок кода расширяет 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 реализовала эту перегрузку.
Environment.Newline
Предпочтительно , чтобы жесткое кодирование либо \n
или \r\n
.
Environment.Newline
предназначен для кроссплатформенной совместимости, а не для работы с файлами, использующими другие окончания строки, чем в текущей операционной системе. Смотрите здесь для получения дополнительной информации , так что это действительно зависит от того, с чем работает разработчик. Использование Environment.Newline
обеспечивает отсутствие согласованности в типе возврата строки между ОС, где «жесткое кодирование» дает разработчику полный контроль.
.Newline
не волшебство, под капотом это просто строки, как указано выше, основанные на переключателе, если он работает на Unix или Windows. Самая безопасная ставка - сначала заменить строку на все "\ r \ n", а затем разделить на "\ n". Когда использование .Newline
не удается, это когда вы работаете с файлами, которые сохранены другими программами, которые используют другой метод для разрывов строк. Это работает хорошо, если вы знаете, что каждый раз, когда файл читается, всегда использует разрывы строк вашей текущей ОС.
foo = foo.Replace("\r\n", "\n"); string[] result = foo.Split('\n');
. Я правильно понимаю, что это работает на всех платформах?
В настоящее время я использую эту функцию (на основе других ответов) в 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
"\r"
= возврат "\r\n"
= возврат + новая строка. (пожалуйста, просмотрите этот пост и принятое решение здесь
Ну, на самом деле сплит должен сделать:
//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]);
}
string[] lines = text.Split(
Environment.NewLine.ToCharArray(),
StringSplitOptions.RemoveEmptyStrings);
В RemoveEmptyStrings гарантирует, что у вас нет пустых записей из-за \ n после \ r
(Изменить, чтобы отразить комментарии :) Обратите внимание, что в тексте также будут отбрасываться подлинные пустые строки. Обычно это то, что я хочу, но это не может быть вашим требованием.
Я не знал о Environment.Newline, но, думаю, это очень хорошее решение.
Моя попытка была бы:
string str = "Test Me\r\nTest Me\nTest Me";
var splitted = str.Split('\n').Select(s => s.Trim()).ToArray();
Дополнительный .Trim удаляет все \ r или \ n, которые могут все еще присутствовать (например, в окнах, но разделение строки символами новой строки os x). Вероятно, не самый быстрый способ, хотя.
РЕДАКТИРОВАТЬ:
Как правильно отмечено в комментариях, это также удаляет все пробелы в начале строки или перед новой строкой. Если вам нужно сохранить этот пробел, используйте один из других вариантов.
Глупый ответ: написать во временный файл, чтобы вы могли использовать почтенный
File.ReadLines
var s = "Hello\r\nWorld";
var path = Path.GetTempFileName();
using (var writer = new StreamWriter(path))
{
writer.Write(s);
}
var lines = File.ReadLines(path);
var
, поскольку он не определяет тип переменной, поэтому вы можете не понимать, как использовать этот объект или что этот объект представляет. Кроме того, это показывает написание строк и даже не указывает имя файла, поэтому я сомневаюсь, что это сработает. Тогда при чтении путь к файлу опять не указывается. Предполагая, что path
это так C:\Temp\test.txt
, вы должны иметь string[] lines = File.ReadLines(path);
.
Path.GetTempFileName
msdn.microsoft.com/en-us/library/… и там написано, что он создает файл с нулевым байтом и возвращает «полный путь к этому файлу». Я мог поклясться, что пытался сделать это раньше, и это дало исключение, потому что он не нашел файл, а вместо этого вернул расположение папки. Я знаю аргументы для использования var
, но я бы сказал, что это НЕ рекомендуется, потому что он не показывает, что такое переменный объект. Это запутывает это.
Очень просто, на самом деле.
VB.NET:
Private Function SplitOnNewLine(input as String) As String
Return input.Split(Environment.NewLine)
End Function
C #:
string splitOnNewLine(string input)
{
return input.split(environment.newline);
}
Environment.NewLine
же, как в VB.