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"
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"
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.
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 > 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 < 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
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 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.
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?
1 Stimmen
Dieses Szenario ist Teil eines viel größeren Problems (die Zeichenfolge ist auch viel größer) und IMO mit Schleifen, hacken Zeichenfolgen usw. ist nicht sehr elegant. StringLength % 4 wird immer 0 sein. Glauben Sie, dass die Verwendung von Schleifen die einzige Lösung ist? Ich möchte keine Kompromisse bei der Leistung eingehen, was ist also die beste Lösung? TIA.
12 Stimmen
Die Verwendung einer einfachen Schleife bringt definitiv die beste Leistung.
0 Stimmen
Sind Sie sicher, dass Linq leistungsfähiger ist als eine for-Schleife? Ich frage mich, was der Unterschied im Unterstreichen der CLR-Sprache am Ende sein würde. Wenn dies wirklich ein Leistungsengpass ist, was seltsam erscheinen würde, dann sollten Sie einige Stresstests durchführen, damit Sie wissen, was bei der erwarteten Belastung schneller ist.
4 Stimmen
nichesoftware.co.nz/blog/200909/linq-vs-loop-performance ist ein ziemlich guter Vergleich zwischen Linq und der tatsächlichen Schleifenbildung über ein Array. Ich bezweifle, dass Linq jemals schneller sein wird als manuell geschriebener Code, da es immer wieder Laufzeitdelegierte aufruft, die nur schwer wegoptimiert werden können. Linq macht aber mehr Spaß :)
2 Stimmen
Ob Sie LINQ oder Regexe verwenden, die Schleife ist immer noch da.
1 Stimmen
Lieber Gott, nein, keine Arrayliste. ArrayListen sind BÖSE