J'ai une chaîne qui contient des chiffres binaires. Comment séparer la chaîne après chaque 8 chiffres?
Supposons que la chaîne soit:
string x = "111111110000000011111111000000001111111100000000";
Je veux ajouter un séparateur comme, (virgule) après chaque 8 caractères.
la sortie doit être:
"11111111,00000000,11111111,00000000,11111111,00000000,"
Ensuite, je veux l'envoyer à une liste <> 8 derniers caractères 1er puis les 8 caractères précédents (sauf,) et ainsi de suite.
Comment puis-je faire ceci?
Regex.Replace(myString, ".{8}", "$0,");
Si vous voulez un tableau de chaînes de huit caractères, 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 la précède.
Essaye ça:
var s = "111111110000000011111111000000001111111100000000";
var list = Enumerable
.Range(0, s.Length/8)
.Select(i => s.Substring(i*8, 8))
.ToList();
var res = string.Join(",", list);
Il existe une autre approche Regex:
var str = "111111110000000011111111000000001111111100000000";
# for .NET 4
var res = String.Join(",",Regex.Matches(str, @"\d{8}").Cast<Match>());
# for .NET 3.5
var res = String.Join(",", Regex.Matches(str, @"\d{8}")
.OfType<Match>()
.Select(m => m.Value).ToArray());
Moche 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);
}
Surcharge de chaîne:
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);
}
... ou vieille école:
public static List<string> splitter(string in, out string csv)
{
if (in.length % 8 != 0) throw new ArgumentException("in");
var lst = new List<string>(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;
}
Si je comprends bien votre dernière exigence (je ne sais pas si vous avez besoin de la chaîne intermédiaire séparée par des virgules ou non), vous pouvez le faire:
var enumerable = "111111110000000011111111000000001111111100000000".Batch(8).Reverse();
En utilisant morelinq .
Ici aussi mes deux petits centimes. Une implémentation utilisant StringBuilder:
public static string AddChunkSeparator (string str, int chunk_len, char separator)
{
if (str == null || str.Length < chunk_len) {
return str;
}
StringBuilder builder = new StringBuilder();
for (var index = 0; index < str.Length; index += chunk_len) {
builder.Append(str, index, chunk_len);
builder.Append(separator);
}
return builder.ToString();
}
Vous pouvez l'appeler comme ceci:
string data = "111111110000000011111111000000001111111100000000";
string output = AddChunkSeparator(data, 8, ',');
Une façon d'utiliser LINQ:
string data = "111111110000000011111111000000001111111100000000";
const int separateOnLength = 8;
string separated = new string(
data.Select((x,i) => i > 0 && i % separateOnLength == 0 ? new [] { ',', x } : new [] { x })
.SelectMany(x => x)
.ToArray()
);
Je l'ai fait en utilisant Pattern & Matcher comme suit:
fun addAnyCharacter(input: String, insertion: String, interval: Int): String {
val pattern = Pattern.compile("(.{$interval})", Pattern.DOTALL)
val matcher = pattern.matcher(input)
return matcher.replaceAll("$1$insertion")
}
Où:
input
indique une chaîne d'entrée. Consultez la section des résultats.
insertion
indique Insérer une chaîne entre ces caractères. Par exemple, virgule (,), début (*), hachage (#).
interval
indique à quel intervalle vous souhaitez ajouter un caractère d'insertion.
input
indique une chaîne d'entrée. Consultez la section des résultats. Vérifiez la section des résultats; ici, j'ai ajouté l'insertion à chaque 4ème caractère.
I/P: 1234XXXXXXXX5678 O/P: 1234 XXXX XXXX 5678
I/P: 1234567812345678 O/P: 1234 5678 1234 5678
I/P: ABCDEFGHIJKLMNOP O/P: ABCD EFGH IJKL MNOP
J'espère que cela t'aides.
C'est beaucoup plus rapide sans copier le tableau (cette version insère de l'espace tous les 3 chiffres mais vous pouvez l'adapter à vos besoins)
public string GetString(double valueField)
{
char[] ins = valueField.ToString().ToCharArray();
int length = ins.Length + (ins.Length / 3);
if (ins.Length % 3 == 0)
{
length--;
}
char[] outs = new char[length];
int i = length - 1;
int j = ins.Length - 1;
int k = 0;
do
{
if (k == 3)
{
outs[i--] = ' ';
k = 0;
}
else
{
outs[i--] = ins[j--];
k++;
}
}
while (i >= 0);
return new string(outs);
}
Pour chaque 1 personnage, vous pouvez faire ce one-liner:
string.Join(".", "1234".ToArray()) //result: 1.2.3.4
Un peu tard pour la fête, mais voici une expression LINQ simplifiée pour diviser une chaîne d'entrée x
en groupes de n
séparés par un autre chaîne sep
:
string sep = ",";
int n = 8;
string result = String.Join(sep, x.InSetsOf(n).Select(g => new String(g.ToArray())));
Un bref aperçu de ce qui se passe ici:
x
est traité comme un IEnumberable<char>
, c'est là qu'intervient la méthode d'extension InSetsOf
.InSetsOf(n)
regroupe les caractères dans un IEnumerable
de IEnumerable
- chaque entrée du groupe externe contient un groupe interne de n
personnages.Select
, chaque groupe de caractères n
est reconverti en chaîne en utilisant le constructeur String()
qui prend un tableau de chars
.Select
est maintenant un IEnumerable<string>
, Qui est passé dans String.Join
Pour entrelacer la chaîne sep
, comme tout autre exemple.