Le moyen le plus simple de diviser une chaîne sur des nouvelles lignes dans .NET?

J’ai besoin de diviser une chaîne en nouvelles lignes dans .NET et la seule façon dont je sais pour diviser les chaînes est d’ utiliser la méthode Split . Cependant, cela ne me permettra pas de (facilement) diviser sur une nouvelle ligne, alors quelle est la meilleure façon de le faire?

Pour diviser une chaîne, vous devez utiliser la surcharge qui prend un tableau de chaînes:

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

Modifier:
Si vous souhaitez gérer différents types de sauts de ligne dans un texte, vous pouvez utiliser la possibilité de faire correspondre plusieurs chaînes. Cela se divisera correctement sur chaque type de saut de ligne et conservera les lignes vides et l’espacement dans le texte:

 ssortingng[] lines = theText.Split( new[] { "\r\n", "\r", "\n" }, SsortingngSplitOptions.None ); 

Qu’en est-il de l’utilisation d’un SsortingngReader ?

 using (System.IO.SsortingngReader reader = new System.IO.SsortingngReader(input)) { ssortingng line = reader.ReadLine(); } 

Vous devriez être capable de diviser votre chaîne assez facilement, comme ceci:

 aSsortingng.Split(Environment.NewLine.ToCharArray()); 

Sur la base de la réponse de Guffa, dans une classe d’extension, utilisez:

 public static ssortingng[] Lines(this ssortingng source) { return source.Split(new ssortingng[] { "\r\n", "\n" }, SsortingngSplitOptions.None); } 

Essayez d’éviter d’utiliser ssortingng.Split pour une solution générale, car vous utiliserez plus de mémoire partout où vous utiliserez la fonction – la chaîne d’origine et la copie fractionnée, toutes deux en mémoire. Croyez-moi, cela peut être un problème énorme lorsque vous commencez à faire évoluer votre système – exécutez une application de traitement par lots 32 bits en traitant 100 Mo de documents, et vous réaliserez huit threads simultanés. Pas que j’y sois allé avant …

Au lieu de cela, utilisez un iterator comme celui-ci;

  public static IEnumerable SplitToLines(this ssortingng input) { if (input == null) { yield break; } using (System.IO.SsortingngReader reader = new System.IO.SsortingngReader(input)) { ssortingng line; while( (line = reader.ReadLine()) != null) { yield return line; } } } 

Cela vous permettra de faire une boucle plus efficace de la mémoire autour de vos données;

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

Bien sûr, si vous voulez tout cela en mémoire, vous pouvez le faire;

 var allTheLines = document.SplitToLines.ToArray(); 

Pour une variable de chaîne s :

 s.Split(new ssortingng[]{Environment.NewLine},SsortingngSplitOptions.None) 

Cela utilise la définition des fins de ligne de votre environnement. Sous Windows, les fins de ligne sont CR-LF (retour chariot, saut de ligne) ou dans les caractères d’échappement C # \r\n .

C’est une solution fiable, car si vous recombinez les lignes avec Ssortingng.Join , cela correspond à votre chaîne d’origine:

 var lines = s.Split(new ssortingng[]{Environment.NewLine},SsortingngSplitOptions.None); var reconstituted = Ssortingng.Join(Environment.NewLine,lines); Debug.Assert(s==reconstituted); 

Ce qu’il ne faut pas faire:

  • Utilisez SsortingngSplitOptions.RemoveEmptyEnsortinges , car cela interrompt le balisage tel que Markdown où les lignes vides ont un but syntaxique.
  • Diviser sur le séparateur new char[]{Environment.NewLine} , car sous Windows, cela créera un élément de chaîne vide pour chaque nouvelle ligne.

Regex est également une option:

  private ssortingng[] SplitSsortingngByLineFeed(ssortingng inpSsortingng) { ssortingng[] locResult = Regex.Split(inpSsortingng, "[\r\n]+"); return locResult; } 

Juste pensé que j’appendais mes deux bits parce que les autres solutions sur cette question ne tombent pas dans la classification de code réutilisable et ne sont pas commodes. Le bloc de code suivant étend l’object ssortingng afin qu’il soit disponible en tant que méthode naturelle lorsque vous travaillez avec des chaînes.

 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 SsortingngExtensions { public static ssortingng[] Split(this ssortingng s, ssortingng delimiter, SsortingngSplitOptions options = SsortingngSplitOptions.None) { return s.Split(new ssortingng[] { delimiter }, options); } } } 

Vous pouvez maintenant utiliser la fonction .Split() de n’importe quelle chaîne comme suit:

 ssortingng[] result; // pass a ssortingng, and the delimiter result = ssortingng.Split("My simple ssortingng", " "); // split an existing ssortingng by delimiter only ssortingng foo = "my - ssortingng - i - want - split"; result = foo.Split("-"); // you can even pass the split options param. when omitted it is // set to SsortingngSplitOptions.None result = foo.Split("-", SsortingngSplitOptions.RemoveEmptyEnsortinges); 

Pour scinder un caractère de nouvelle ligne, il suffit de passer "\n" ou "\r\n" comme paramètre de délimiteur.

Commentaire: Ce serait bien si Microsoft implémentait cette surcharge.

J’utilise actuellement cette fonction (basée sur d’autres réponses) dans VB.NET:

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

Il essaie d’abord de diviser sur la nouvelle ligne de la plate-forme, puis de revenir à chaque nouvelle ligne possible.

Je n’avais besoin de cela que dans une classe jusqu’à présent. Si cela change, je vais probablement rendre ce Public et le déplacer dans une classe utilitaire, et peut-être même en faire une méthode d’extension.

Voici comment relier les lignes, pour faire bonne mesure:

 Private Shared Function JoinLines(lines As IEnumerable(Of Ssortingng)) As Ssortingng Return Ssortingng.Join(Environment.NewLine, lines) End Function 

Eh bien, effectivement divisé devrait faire:

 //Constructing ssortingng... SsortingngBuilder sb = new SsortingngBuilder(); sb.AppendLine("first line"); sb.AppendLine("second line"); sb.AppendLine("third line"); ssortingng s = sb.ToSsortingng(); Console.WriteLine(s); //Splitting multiline ssortingng into separate lines ssortingng[] splitted = s.Split(new ssortingng[] {System.Environment.NewLine}, SsortingngSplitOptions.RemoveEmptyEnsortinges); // Output (separate lines) for( int i = 0; i < splitted.Count(); i++ ) { Console.WriteLine("{0}: {1}", i, splitted[i]); } 
 ssortingng[] lines = text.Split( Environment.NewLine.ToCharArray(), SsortingngSplitOptions.RemoveEmptySsortingngs); 

L’option RemoveEmptySsortingngs s’assurera que vous n’avez pas d’entrées vides en raison de \ n qui suit un \ r

(Modifier pour refléter les commentaires 🙂 Notez que cela supprimera également les véritables lignes vides dans le texte. C’est généralement ce que je veux mais ce n’est peut-être pas votre exigence.

Je ne connaissais pas Environment.Newline, mais je suppose que c’est une très bonne solution.

Mon essai aurait été:

  ssortingng str = "Test Me\r\nTest Me\nTest Me"; var splitted = str.Split('\n').Select(s => s.Trim()).ToArray(); 

Le .Trim supplémentaire supprime tous les \ r ou \ n qui pourraient être encore présents (par exemple, dans Windows, mais en divisant une chaîne par des caractères de nouvelle ligne os x). Probablement pas la méthode la plus rapide.

MODIFIER:

Comme le soulignent les commentaires, cela supprime également tout espace au début de la ligne ou avant le nouveau saut de ligne. Si vous devez conserver cet espace, utilisez l’une des autres options.

Silly answer: écrivez dans un fichier temporaire pour pouvoir utiliser les vénérables 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); 
 // using System.IO; ssortingng textToSplit; if(textToSplit!=null) { List lines = new List(); using (SsortingngReader reader = new SsortingngReader(textToSplit)) { for (ssortingng line = reader.ReadLine(); line != null;line = reader.ReadLine()) { lines.Add(line); } } } 

Très facile, en fait.

VB.NET:

 Private Function SplitOnNewLine(input as Ssortingng) As Ssortingng Return input.Split(Environment.NewLine) End Function 

C #:

 ssortingng splitOnNewLine(ssortingng input) { return input.split(environment.newline); }