web-dev-qa-db-de.com

Fügen Sie bei allen N Zeichen ein Trennzeichen zur Zeichenfolge hinzu?

Ich habe eine Zeichenfolge, die Binärziffern enthält. Wie trenne ich eine Zeichenfolge nach jeder 8-stelligen?

Angenommen, die Zeichenfolge lautet:

string x = "111111110000000011111111000000001111111100000000";

Ich möchte nach jedem 8-stelligen Zeichen ein Trennzeichen wie (Komma) einfügen.

die Ausgabe sollte sein:

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

Dann möchte ich es an eine Liste senden, die <> die letzten 8 Zeichen, die ersten 8 Zeichen (mit Ausnahme von,) und so weiter enthält.

Wie kann ich das machen?

63
Abdur Rahim
Regex.Replace(myString, ".{8}", "$0,");

Wenn Sie ein Array mit acht Zeichenfolgen benötigen, ist das wahrscheinlich einfacher:

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

dadurch wird die Zeichenfolge nur an Punkten aufgeteilt, an denen ein Vielfaches von acht Zeichen davor steht.

109
Joey

Versuche dies:

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

Es gibt einen anderen Regex-Ansatz:

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());
3
Alex

Hässlicher aber weniger Müll:

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

String-Überladung:

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);
}
3
Johan Larsson

... oder alte Schule:

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

Wenn ich Ihre letzte Anforderung richtig verstehe (mir ist nicht klar, ob Sie die durch Kommas getrennte Zwischenzeichenfolge benötigen oder nicht), können Sie dies tun:

var enumerable = "111111110000000011111111000000001111111100000000".Batch(8).Reverse();

Mit morelinq .

2
David Peden

Hier meine zwei kleinen Cents auch. Eine Implementierung mit 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();
        }

Sie können es so nennen:

string data = "111111110000000011111111000000001111111100000000";
string output = AddChunkSeparator(data, 8, ',');
1
C.M.

Ein Weg mit 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()
    );
1
driis

Ich habe es mit Pattern & Matcher wie folgt gemacht:

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

Woher:

input gibt die Eingabezeichenfolge an. Überprüfen Sie den Ergebnisbereich.

insertion gibt an, dass eine Zeichenfolge zwischen diesen Zeichen eingefügt werden soll. Zum Beispiel Komma (,), Start (*), Raute (#).

interval gibt an, in welchem ​​Intervall Sie ein Einfügezeichen hinzufügen möchten.

input gibt die Eingabezeichenfolge an. Überprüfen Sie den Ergebnisbereich. Ergebnisbereich prüfen; hier habe ich bei jedem 4. Zeichen eine Einfügung hinzugefügt.

Ergebnisse:

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

Hoffe das hilft.

0
Hiren Patel

Dies geht viel schneller, ohne das Array zu kopieren (diese Version fügt alle 3 Stellen Leerzeichen ein, aber Sie können es an Ihre Bedürfnisse anpassen).

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

Für jeden 1 Charakter können Sie diesen Einzeiler machen:

string.Join(".", "1234".ToArray()) //result: 1.2.3.4
0
Ma Dude

Ein bisschen zu spät zur Party, aber hier ist ein vereinfachter LINQ-Ausdruck, um eine Eingabezeichenfolge x in Gruppen von n zu unterteilen, die durch eine andere getrennt sind Zeichenfolge sep:

string sep = ",";
int n = 8;
string result = String.Join(sep, x.InSetsOf(n).Select(g => new String(g.ToArray())));

Ein kurzer Überblick darüber, was hier passiert:

  • x wird als IEnumberable<char> behandelt. Hier kommt die Erweiterungsmethode InSetsOf zum Einsatz.
  • InSetsOf(n) gruppiert Zeichen in einem IEnumerable von IEnumerable - jeder Eintrag in der äußeren Gruppierung enthält eine innere Gruppe von n Zeichen.
  • Innerhalb der Select -Methode wird jede Gruppe von n -Zeichen mithilfe des String() -Konstruktors, der ein Array von chars annimmt, in einen String umgewandelt.
  • Das Ergebnis von Select ist jetzt ein IEnumerable<string>, Der an String.Join Übergeben wird, um die Zeichenfolge sep wie in jedem anderen Beispiel zu verschachteln.
0
Dusty