Добавить разделитель в строку в каждом N символов? - PullRequest
61 голосов
/ 29 марта 2012

У меня есть строка, которая содержит двоичные цифры.Как отделить строку после каждых 8 цифр?

Предположим, что строка:

string x = "111111110000000011111111000000001111111100000000";

Я хочу добавить разделитель (запятую) после каждых 8 символов.

выходные данные должны быть:

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

Затем я хочу отправить его в список <> последние 8 символов 1-го, затем предыдущие 8 символов (исключая,) и т. д.

Как можноЯ делаю это?

Ответы [ 13 ]

107 голосов
/ 29 марта 2012
Regex.Replace(myString, ".{8}", "$0,");

Если вам нужен массив из восьмисимвольных строк, то следующее, вероятно, проще:

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

, который разбивает строку только в точках, где ей предшествует кратное восьми символов.

35 голосов
/ 29 марта 2012

Попробуйте это:

var s = "111111110000000011111111000000001111111100000000";
var list = Enumerable
    .Range(0, s.Length/8)
    .Select(i => s.Substring(i*8, 8))
    .ToList();
var res = string.Join(",", list);
3 голосов
/ 22 апреля 2014

Ужасно, но меньше мусора:

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

Перегрузка строки:

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 голосов
/ 29 марта 2012

Существует другой подход к 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());
2 голосов
/ 29 марта 2012

... или старая школа:

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 голосов
/ 29 марта 2012

Если я правильно понимаю ваше последнее требование (мне непонятно, нужна ли вам промежуточная строка с разделителями-запятыми или нет), вы можете сделать это:

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

Используя morelinq .

1 голос
/ 27 июня 2018

Вот мои два маленьких цента тоже. Реализация с использованием 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();
        }

Вы можете назвать это так:

string data = "111111110000000011111111000000001111111100000000";
string output = AddChunkSeparator(data, 8, ',');
1 голос
/ 29 марта 2012

В одну сторону, используя 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()
    );
0 голосов
/ 19 марта 2019

Я сделал это, используя Pattern & Matcher следующим образом:

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

Где:

input обозначает строку ввода. Раздел результатов проверки.

insertion указывает строку вставки между этими символами. Например запятая (,), начало (*), хэш (#).

interval указывает, через какой интервал вы хотите добавить символ вставки.

input обозначает строку ввода. Проверьте результаты раздела. Раздел результатов проверки; здесь я добавил вставку для каждого 4-го символа.

Результаты:

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

Надеюсь, это поможет.

0 голосов
/ 10 апреля 2018

Для каждого 1 символа, вы можете сделать это одной строкой:

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