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?

38voto

Magnetron Punkte 5977

Ab .NET 6 können wir auch die Chunk Methode:

var result = str
    .Chunk(4)
    .Select(x => new string(x))
    .ToList();

26voto

Alan Moore Punkte 70949

Wie wäre es mit diesem Einzeiler?

List<string> result = new List<string>(Regex.Split(target, @"(?<=\G.{4})", RegexOptions.Singleline));

Bei dieser Regex spielt es keine Rolle, ob das letzte Stück weniger als vier Zeichen hat, denn es werden immer nur die Zeichen dahinter berücksichtigt.

Ich bin mir sicher, dass dies nicht die effizienteste Lösung ist, aber ich musste sie einfach mal ausprobieren.

8voto

Guffa Punkte 663241

Es ist nicht schön und nicht schnell, aber es funktioniert, es ist ein Einzeiler und es ist LINQy:

List<string> a = text.Select((c, i) => new { Char = c, Index = i }).GroupBy(o => o.Index / 4).Select(g => new String(g.Select(o => o.Char).ToArray())).ToList();

8voto

Michael Nelson Punkte 141

Ich musste kürzlich etwas schreiben, das dies bei der Arbeit erreicht, also dachte ich, ich würde meine Lösung für dieses Problem veröffentlichen. Als zusätzlichen Bonus bietet die Funktionalität dieser Lösung eine Möglichkeit, die Zeichenkette in die entgegengesetzte Richtung aufzuteilen, und sie behandelt Unicode-Zeichen korrekt, wie bereits von Marvin Pinto oben erwähnt. Also, hier ist sie:

using System;
using Extensions;

namespace TestCSharp
{
    class Program
    {
        static void Main(string[] args)
        {    
            string asciiStr = "This is a string.";
            string unicodeStr = "";

            string[] array1 = asciiStr.Split(4);
            string[] array2 = asciiStr.Split(-4);

            string[] array3 = asciiStr.Split(7);
            string[] array4 = asciiStr.Split(-7);

            string[] array5 = unicodeStr.Split(5);
            string[] array6 = unicodeStr.Split(-5);
        }
    }
}

namespace Extensions
{
    public static class StringExtensions
    {
        /// <summary>Returns a string array that contains the substrings in this string that are seperated a given fixed length.</summary>
        /// <param name="s">This string object.</param>
        /// <param name="length">Size of each substring.
        ///     <para>CASE: length &gt; 0 , RESULT: String is split from left to right.</para>
        ///     <para>CASE: length == 0 , RESULT: String is returned as the only entry in the array.</para>
        ///     <para>CASE: length &lt; 0 , RESULT: String is split from right to left.</para>
        /// </param>
        /// <returns>String array that has been split into substrings of equal length.</returns>
        /// <example>
        ///     <code>
        ///         string s = "1234567890";
        ///         string[] a = s.Split(4); // a == { "1234", "5678", "90" }
        ///     </code>
        /// </example>            
        public static string[] Split(this string s, int length)
        {
            System.Globalization.StringInfo str = new System.Globalization.StringInfo(s);

            int lengthAbs = Math.Abs(length);

            if (str == null || str.LengthInTextElements == 0 || lengthAbs == 0 || str.LengthInTextElements <= lengthAbs)
                return new string[] { str.ToString() };

            string[] array = new string[(str.LengthInTextElements % lengthAbs == 0 ? str.LengthInTextElements / lengthAbs: (str.LengthInTextElements / lengthAbs) + 1)];

            if (length > 0)
                for (int iStr = 0, iArray = 0; iStr < str.LengthInTextElements && iArray < array.Length; iStr += lengthAbs, iArray++)
                    array[iArray] = str.SubstringByTextElements(iStr, (str.LengthInTextElements - iStr < lengthAbs ? str.LengthInTextElements - iStr : lengthAbs));
            else // if (length < 0)
                for (int iStr = str.LengthInTextElements - 1, iArray = array.Length - 1; iStr >= 0 && iArray >= 0; iStr -= lengthAbs, iArray--)
                    array[iArray] = str.SubstringByTextElements((iStr - lengthAbs < 0 ? 0 : iStr - lengthAbs + 1), (iStr - lengthAbs < 0 ? iStr + 1 : lengthAbs));

            return array;
        }
    }
}

Außerdem finden Sie hier einen Link zu den Ergebnissen der Ausführung dieses Codes: http://i.imgur.com/16Iih.png

6voto

Jeff Mercado Punkte 120818

Dies sollte viel schneller und effizienter sein als die Verwendung von LINQ oder anderen hier verwendeten Ansätzen.

public static IEnumerable<string> Splice(this string s, int spliceLength)
{
    if (s == null)
        throw new ArgumentNullException("s");
    if (spliceLength < 1)
        throw new ArgumentOutOfRangeException("spliceLength");

    if (s.Length == 0)
        yield break;
    var start = 0;
    for (var end = spliceLength; end < s.Length; end += spliceLength)
    {
        yield return s.Substring(start, spliceLength);
        start = end;
    }
    yield return s.Substring(start);
}

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