Moyen le plus simple de diviser une chaîne sur les retours à la ligne in.NET?

J'ai besoin de diviser une chaîne en sauts de ligne dans.NET et la seule façon que je connaisse de diviser les chaînes est avec 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?

646
demandé sur Peter Mortensen 2009-10-10 13:25:56

15 réponses

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

string[] lines = theText.Split(
    new[] { Environment.NewLine },
    StringSplitOptions.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 plus d'une chaîne. Cela se divisera correctement sur l'un ou l'autre type de saut de ligne, et préservera les lignes vides et l'espacement dans le texte:

string[] lines = theText.Split(
    new[] { "\r\n", "\r", "\n" },
    StringSplitOptions.None
);
1152
répondu Guffa 2017-10-16 21:25:25

Qu'en est-il de l'utilisation d'un StringReader?

using (System.IO.StringReader reader = new System.IO.StringReader(input)) {
    string line = reader.ReadLine();
}
87
répondu Clément 2014-05-09 14:52:27

Vous devriez pouvoir diviser votre chaîne assez facilement, comme ceci:

aString.Split(Environment.NewLine.ToCharArray());
40
répondu nikmd23 2009-10-10 09:29:44

Basé sur la réponse de Guffa, dans une classe d'extension, Utilisez:

public static string[] Lines(this string source) {
    return source.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
}
23
répondu Erwin Mayer 2011-06-02 15:34:15

Essayez d'éviter d'utiliser de la chaîne.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, à la fois en mémoire. Croyez-moi que cela peut être un sacré problème lorsque vous commencez à mettre à l'échelle-exécutez une application de traitement par lots 32 bits traitant des documents 100MB, et vous allez chier à Huit threads simultanés. Non pas que j'ai été là avant...

À la place, utilisez un itérateur comme celui-ci;

    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;
            }
        }
    }

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

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

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

var allTheLines = document.SplitToLines.ToArray();
23
répondu Steve Cooper 2014-05-01 12:49:39

Pour une variable de chaîne s:

s.Split(new string[]{Environment.NewLine},StringSplitOptions.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 de C#\r\n.

C'est une solution fiable, car si vous recombinez les lignes avec String.Join, ceci est égal à votre chaîne d'origine:

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

Ce qu'il ne faut pas faire:

  • Utilisation StringSplitOptions.RemoveEmptyEntries, parce que cela va casser le balisage tel que Markdown où les lignes vides ont syntaxique but.
  • Split sur separator new char[]{Environment.NewLine}, car sous Windows, cela créera un élément de chaîne vide pour chaque nouvelle ligne.
8
répondu Colonel Panic 2013-05-14 19:51:50

Regex est également une option:

    private string[] SplitStringByLineFeed(string inpString)
    {
        string[] locResult = Regex.Split(inpString, "[\r\n]+");
        return locResult;
    }
6
répondu user1964822 2013-01-09 22:02:53

Je pensais juste ajouter 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 pratiques. Le bloc de code suivant étend l'objet string 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 StringExtensions
    {
        public static string[] Split(this string s, string delimiter, StringSplitOptions options = StringSplitOptions.None)
        {
            return s.Split(new string[] { delimiter }, options);
        }
    }
}

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

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 param. when omitted it is
// set to StringSplitOptions.None
result = foo.Split("-", StringSplitOptions.RemoveEmptyEntries);

Pour diviser sur un caractère de nouvelle ligne, passez simplement "\n" ou "\r\n" comme paramètre de délimiteur.

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

6
répondu Kraang Prime 2016-07-10 16:33:14

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

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

Il essaie d'abord de diviser sur la nouvelle ligne locale de la plate-forme, puis revient à chaque nouvelle ligne possible.

J'ai seulement eu besoin de cela dans une classe jusqu'à présent. Si cela change, je vais probablement faire ceci Public et le déplacer vers une classe utilitaire, et peut-être même en faire une méthode d'extension.

Voici comment rejoindre les lignes, pour faire bonne mesure:

Private Shared Function JoinLines(lines As IEnumerable(Of String)) As String
    Return String.Join(Environment.NewLine, lines)
End Function
4
répondu Rory O'Kane 2013-05-14 19:35:26

Eh bien, en fait split devrait faire:

//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]);
}
2
répondu MaciekTalaska 2015-05-31 17:09:51
string[] lines = text.Split(
  Environment.NewLine.ToCharArray(), 
  StringSplitOptions.RemoveEmptyStrings);

L'option RemoveEmptyStrings s'assurera que vous n'avez pas d'entrées vides en raison de \n suivant un \ r

(Modifier pour refléter les commentaires:) notez qu'il supprimera également les lignes vides authentiques dans le texte. C'est généralement ce que je veux, mais ce n'est peut-être pas votre exigence.

1
répondu Serge Wautier 2009-10-10 10:21:46

Je ne connaissais pas L'environnement.Nouvelle ligne, mais je suppose que c'est une très bonne solution.

Mon essai aurait été:

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

Le supplément .Trim supprime tout \r ou \n qui pourrait être encore présent (par exemple sous windows, mais en divisant une chaîne avec des caractères de nouvelle ligne os x). Probablement pas la méthode la plus rapide mais.

Modifier:

Comme les commentaires l'ont correctement souligné, cela supprime également tout espace au début de la ligne ou avant le nouveau saut de ligne. Si vous avez besoin d' pour conserver cet espace, utilisez l'une des autres options.

0
répondu Max 2009-10-10 11:57:44

Réponse Stupide: écrivez dans un fichier temporaire afin que vous puissiez utiliser le vénérable 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);
-1
répondu Colonel Panic 2012-10-04 16:13:07
// using System.IO;

string textToSplit;

  if(textToSplit!=null)
   {
    List<string> lines = new List<string>();
    using (StringReader reader = new StringReader(textToSplit))
    {
        for (string line = reader.ReadLine(); line != null;line = reader.ReadLine())
        {
            lines.Add(line);
        }
    }
   }
-1
répondu maciej 2014-07-20 15:18:00

Très facile, en fait.

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);
}
-3
répondu Skillaura13 2017-07-07 21:05:37