Мені потрібно розділити рядок на нові рядки в .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 немає цих послідовностей евакуації, тому там замість них використовуються ці константи.
Що з використанням a 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 (повернення каретки, канал рядка) або символи втечі 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 це створить один порожній рядовий елемент для кожного нового рядка.Регекс - це також варіант:
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, який може бути присутнім (наприклад, коли у Windows, але розділяє рядок із символами os x newline). Напевно, не найшвидший метод.
Редагувати:
Як правильно зазначалося в коментарях, це також видаляє пробіли на початку рядка або перед подачею нового рядка. Якщо вам потрібно зберегти цей пробіл, використовуйте один з інших варіантів.
Нерозумна відповідь: пишіть у тимчасовий файл, щоб ви могли користуватися поважними
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.