267 votes

Découpage d'une chaîne de caractères en morceaux d'une certaine taille

Supposons que j'ai une chaîne de caractères :

string str = "1111222233334444"; 

Comment puis-je diviser cette chaîne en morceaux d'une certaine taille ?

Par exemple, le découpage en tailles de 4 renverrait des chaînes de caractères :

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

26voto

Alan Moore Points 39365

Que dites-vous de ça pour une remarque ?

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

Avec cette regex, il importe peu que le dernier morceau soit inférieur à quatre caractères, car elle ne prend en compte que les caractères qui le suivent. Je suis sûr que ce n'est pas la solution la plus efficace, mais je devais juste la proposer :D

8voto

Guffa Points 308133

Ce n'est pas très joli et ce n'est pas rapide, mais ça marche, c'est en une seule ligne et c'est LINQy :

List<string> a = text.ToCharArray().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 Points 61

J'ai récemment dû rédiger un texte à cet effet dans le cadre de mon travail, et j'ai donc pensé poster ma solution à ce problème. En prime, la fonctionnalité de cette solution permet de diviser la chaîne de caractères dans la direction opposée et elle gère correctement les caractères unicode, comme l'a mentionné Marvin Pinto ci-dessus. Donc, voici la solution :

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

En outre, voici un lien image vers les résultats de l'exécution de ce code : http://i.imgur.com/16Iih.png

6voto

Jeff Mercado Points 42075

Cela devrait être beaucoup plus rapide et plus efficace que l'utilisation de LINQ ou d'autres approches utilisées ici.

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

5voto

Habib Points 93087

Vous pouvez utiliser morelinq par Jon Skeet. Utilisez Lot comme :

string str = "1111222233334444";
int chunkSize = 4;
var chunks = str.Batch(chunkSize).Select(r => new String(r.ToArray()));

Ceci retournera 4 morceaux pour la chaîne de caractères "1111222233334444" . Si la longueur de la chaîne est inférieure ou égale à la taille du chunk Batch retournera la chaîne de caractères comme seul élément de IEnumerable<string>

Pour la sortie :

foreach (var chunk in chunks)
{
    Console.WriteLine(chunk);
}

et il donnera :

1111
2222
3333
4444

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X