93 votes

Ajouter un séparateur à la chaîne à chaque N caractères?

J'ai une chaîne de caractères qui contient des chiffres binaires. Comment séparer la chaîne après chaque groupe de 8 chiffres ?

Supposons que la chaîne soit :

string x = "111111110000000011111111000000001111111100000000";

Je veux ajouter un séparateur comme une virgule (,) après chaque groupe de 8 caractères.

Le résultat devrait être :

"11111111,00000000,11111111,00000000,11111111,00000000,"

Ensuite, je veux l'envoyer à une liste<> en commençant par les 8 derniers caractères, puis les 8 caractères précédents (en excluant la virgule) et ainsi de suite.

Comment puis-je faire cela ?

1 votes

Vous pouvez utiliser un tableau de caractères ou d'octets.

4 votes

0 votes

Est-ce que je peux faire la première chose avec string.Format()?si oui, comment?

153voto

Joey Points 148544
Regex.Replace(myString, ".{8}", "$0,");

Si vous voulez un tableau de chaînes de huit caractères, alors ce qui suit est probablement plus simple:

Regex.Split(myString, "(?<=^(.{8})+)");

qui divisera la chaîne uniquement aux points où un multiple de huit caractères le précède.

1 votes

Il pourrait être utile d'affirmer qu'il ne s'agit que de "chiffres" binaires, et non de caractères : "[01]{8}"

4 votes

Eh bien, j'espère qu'ils savent quel type de données ils jettent là-dedans :)

0 votes

Pouvez-vous m'expliquer la partie "$0,"? Je ne suis pas tout à fait sûr de comment cette expression doit être lue/évaluée.

47voto

dasblinkenlight Points 264350

Essayez ceci :

var s = "111111110000000011111111000000001111111100000000";
var list = Enumerable
    .Range(0, s.Length/8)
    .Select(i => s.Substring(i*8, 8));
var res = string.Join(",", list);

0 votes

Oui en effet... Merci @dasbinkeblight

2 votes

Vous n'avez pas besoin du ToList() d'ailleurs, car string.Join a une surcharge qui prend un IEnumerable (depuis .NET 4).

1 votes

@Joey Je sais, mais j'ai initialement mal compris la question. J'ai lu la partie où l'OP dit "Then i want to send it to a list<>" et j'ai posté une réponse avec ToList() et aucune ligne string.Join. Ensuite, j'ai relu la question, ajouté res = ..., et enregistré, mais j'ai oublié de supprimer ToList().

4voto

Alex Points 4265

Il existe une autre approche Regex :

var str = "111111110000000011111111000000001111111100000000";
# pour .NET 4
var res = String.Join(",",Regex.Matches(str, @"\d{8}").Cast());

# pour .NET 3.5
var res = String.Join(",", Regex.Matches(str, @"\d{8}")
            .OfType()
            .Select(m => m.Value).ToArray());

0 votes

J'aime cette approche car les "pièces sont compréhensibles", même s'il faut un peu plus de fudge dans .NET 3.5

0 votes

Merci pour les ajouts :) - J'oublie toujours de vérifier la compatibilité du framework.

1 votes

Ce code supprime les caractères. Les séparateurs seront remplacés par une chaîne de caractères et la chaîne de caractères sera perdue.

3voto

Wolf5370 Points 936

...ou à l'ancienne :

public static List splitter(string in, out string csv)
{
     if (in.length % 8 != 0) throw new ArgumentException("in");
     var lst = new List(in/8);

     for (int i=0; i < in.length / 8; i++) lst.Add(in.Substring(i*8,8));

     csv = string.Join(",", lst); //This we want in input order (I believe)
     lst.Reverse(); //As we want list in reverse order (I believe)

     return lst;
}

1 votes

Je trouve cela facile à lire - mais chacun ses goûts :D En dehors des méthodes Regex ici, c'est ce que font les méthodes Linq en coulisses - boucler et découper au fur et à mesure - mais beaucoup plus facile à lire. J'aime bien la méthode Batch ci-dessus, c'est une nouveauté pour moi :)

0 votes

Cela ne compilera même pas, car length n'est pas un membre de System.String.

3voto

Johan Larsson Points 4405

Laide mais moins de déchets:

private string InsertStrings(string s, int insertEvery, char insert)
{
    char[] ins = s.ToCharArray();
    int length = s.Length + (s.Length / insertEvery);
    if (ins.Length % insertEvery == 0)
    {
        length--;
    }
    var outs = new char[length];
    long di = 0;
    long si = 0;
    while (si < s.Length - insertEvery)
    {
        Array.Copy(ins, si, outs, di, insertEvery);
        si += insertEvery;
        di += insertEvery;
        outs[di] = insert;
        di ++;
    }
    Array.Copy(ins, si, outs, di, ins.Length - si);
    return new string(outs);
}

Surchage de chaînes:

private string InsertStrings(string s, int insertEvery, string insert)
{
    char[] ins = s.ToCharArray();
    char[] inserts = insert.ToCharArray();
    int insertLength = inserts.Length;
    int length = s.Length + (s.Length / insertEvery) * insert.Length;
    if (ins.Length % insertEvery == 0)
    {
        length -= insert.Length;
    }
    var outs = new char[length];
    long di = 0;
    long si = 0;
    while (si < s.Length - insertEvery)
    {
        Array.Copy(ins, si, outs, di, insertEvery);
        si += insertEvery;
        di += insertEvery;
        Array.Copy(inserts, 0, outs, di, insertLength);
        di += insertLength;
    }
    Array.Copy(ins, si, outs, di, ins.Length - si);
    return new string(outs);
}

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