277 Stimmen

Aufteilung einer Zeichenkette in Stücke einer bestimmten Größe

Angenommen, ich hätte eine Zeichenkette:

string str = "1111222233334444"; 

Wie kann ich diese Zeichenfolge in Stücke einer bestimmten Größe zerlegen?

Die Aufteilung in 4 Größen würde z. B. Zeichenketten ergeben:

"1111"
"2222"
"3333"
"4444"

19 Stimmen

Warum LINQ oder Regexe verwenden, wenn die Standardfunktionen von C# zur Stringmanipulation dies mit weniger Aufwand und mehr Geschwindigkeit erledigen können? Was passiert außerdem, wenn die Zeichenfolge eine ungerade Anzahl von Zeichen lang ist?

0 Stimmen

Ich würde gerne Schleifen usw. vermeiden. Ich denke, es kann in einer Zeile mit LINQ/Regex getan werden.

8 Stimmen

"Ich möchte Schleifen vermeiden" - warum?

301voto

Konstantin Spirin Punkte 19144
static IEnumerable<string> Split(string str, int chunkSize)
{
    return Enumerable.Range(0, str.Length / chunkSize)
        .Select(i => str.Substring(i * chunkSize, chunkSize));
}

Bitte beachten Sie, dass zusätzlicher Code erforderlich sein kann, um Randfälle korrekt zu behandeln ( null oder leere Eingabezeichenfolge, chunkSize == 0 , Länge der Eingabezeichenfolge nicht teilbar durch chunkSize , usw.). Die ursprüngliche Frage spezifiziert keine Anforderungen für diese Randfälle, und im wirklichen Leben können die Anforderungen variieren, so dass sie außerhalb des Anwendungsbereichs dieser Antwort liegen.

177voto

Eamon Nerbonne Punkte 45041

In einer Kombination aus den Antworten von dove+Konstatin...

static IEnumerable<string> WholeChunks(string str, int chunkSize) {
    for (int i = 0; i < str.Length; i += chunkSize) 
        yield return str.Substring(i, chunkSize);
}

Dies funktioniert für alle Zeichenketten, die in eine ganze Anzahl von Abschnitten aufgeteilt werden können, und löst andernfalls eine Ausnahme aus.

Wenn Sie Zeichenketten beliebiger Länge unterstützen möchten, können Sie den folgenden Code verwenden:

static IEnumerable<string> ChunksUpto(string str, int maxChunkSize) {
    for (int i = 0; i < str.Length; i += maxChunkSize) 
        yield return str.Substring(i, Math.Min(maxChunkSize, str.Length-i));
}

Der Auftraggeber hat jedoch ausdrücklich erklärt, dass er no brauchen; sie ist etwas länger und schwieriger zu lesen, etwas langsamer. Im Sinne von KISS und YAGNI würde ich mich für die erste Option entscheiden: Sie ist wahrscheinlich die effizienteste Implementierung, die möglich ist, und sie ist sehr kurz, lesbar und, was wichtig ist, löst eine Ausnahme für nicht konforme Eingaben aus.

63voto

dove Punkte 20015

Warum keine Schleifen? Hier ist etwas, das es ganz gut machen würde:

        string str = "111122223333444455";
        int chunkSize = 4;
        int stringLength = str.Length;
        for (int i = 0; i < stringLength ; i += chunkSize)
        {
            if (i + chunkSize > stringLength) chunkSize = stringLength  - i;
            Console.WriteLine(str.Substring(i, chunkSize));

        }
        Console.ReadLine();

Ich weiß nicht, wie Sie mit dem Fall, wo die Zeichenfolge nicht Faktor von 4, aber nicht sagen, Sie Idee ist nicht möglich, nur wundern die Motivation für es, wenn eine einfache for-Schleife es sehr gut tut umgehen würde? Natürlich könnte die oben genannten bereinigt werden und sogar in als eine Erweiterung Methode setzen.

Oder wie in den Kommentaren erwähnt, wissen Sie, dass es dann /4 ist

str = "1111222233334444";
for (int i = 0; i < stringLength; i += chunkSize) 
  {Console.WriteLine(str.Substring(i, chunkSize));}

49voto

oleksii Punkte 34441

Die Grundlage hierfür sind @Taubenlösung sondern als Erweiterungsmethode implementiert.

Vorteile:

  • Methode der Erweiterung
  • Deckt Eckfälle ab
  • Zerlegt eine Zeichenkette mit beliebigen Zeichen: Zahlen, Buchstaben, andere Symbole

Code

public static class EnumerableEx
{    
    public static IEnumerable<string> SplitBy(this string str, int chunkLength)
    {
        if (String.IsNullOrEmpty(str)) throw new ArgumentException();
        if (chunkLength < 1) throw new ArgumentException();

        for (int i = 0; i < str.Length; i += chunkLength)
        {
            if (chunkLength + i > str.Length)
                chunkLength = str.Length - i;

            yield return str.Substring(i, chunkLength);
        }
    }
}

Verwendung

var result = "bobjoecat".SplitBy(3); // bob, joe, cat

Einheitstests aus Gründen der Kürze entfernt (siehe vorherige Revision )

45voto

João Silva Punkte 84947

Verwendung von reguläre Ausdrücke y Linq :

List<string> groups = (from Match m in Regex.Matches(str, @"\d{4}")
                       select m.Value).ToList();

Ich finde, dass dies besser lesbar ist, aber das ist nur eine persönliche Meinung. Es kann auch ein Einzeiler sein : ).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X