Add separator to string at every N characters?

C#StringGroupingString Formatting

C# Problem Overview


I have a string which contains binary digits. How to separate string after each 8 digit?

Suppose the string is:

string x = "111111110000000011111111000000001111111100000000";

I want to add a separator like ,(comma) after each 8 character.

output should be :

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

Then I want to send it to a list<> last 8 char 1st then the previous 8 chars(excepting ,) and so on.

How can I do this?

C# Solutions


Solution 1 - C#

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

If you want an array of eight-character strings, then the following is probably easier:

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

which will split the string only at points where a multiple of eight characters precede it.

Solution 2 - C#

Try this:

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

Solution 3 - C#

There's another Regex approach:

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

Solution 4 - C#

...or old school:

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

Solution 5 - C#

Ugly but less garbage:

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 overload:

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

Solution 6 - C#

If I understand your last requirement correctly (it's not clear to me if you need the intermediate comma-delimited string or not), you could do this:

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

By utilizing morelinq.

Solution 7 - C#

One way using 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()
	);

Solution 8 - C#

Here my two little cents too. An implementation using 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();
		}

You can call it like this:

string data = "111111110000000011111111000000001111111100000000";
string output = AddChunkSeparator(data, 8, ',');

Solution 9 - C#

I did it using Pattern & Matcher as following way:

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

Where:

input indicates Input string. Check results section.

insertion indicates Insert string between those characters. For example comma (,), start(*), hash(#).

interval indicates at which interval you want to add insertion character.

input indicates Input string. Check results section. Check results section; here I've added insertion at every 4th character.

Results:

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

Hope this helps.

Solution 10 - C#

This is much faster without copying array (this version inserts space every 3 digits but you can adjust it to your needs)

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

Solution 11 - C#

A little late to the party, but here's a simplified LINQ expression to break an input string x into groups of n separated by another string sep:

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

A quick rundown of what's happening here:

  • x is being treated as an IEnumberable<char>, which is where the InSetsOf extension method comes in.
  • InSetsOf(n) groups characters into an IEnumerable of IEnumerable -- each entry in the outer grouping contains an inner group of n characters.
  • Inside the Select method, each group of n characters is turned back into a string by using the String() constructor that takes an array of chars.
  • The result of Select is now an IEnumerable<string>, which is passed into String.Join to interleave the sep string, just like any other example.

Solution 12 - C#

If you intend to create your own function to acheive this without using regex or pattern matching methods, you can create a simple function like this:

String formatString(String key, String seperator, int afterEvery){
        String formattedKey = "";
        for(int i=0; i<key.length(); i++){
            formattedKey += key.substring(i,i+1);
            if((i+1)%afterEvery==0)
                formattedKey += seperator;
        }
        if(formattedKey.endsWith("-"))
            formattedKey = formattedKey.substring(0,formattedKey.length()-1);
        return formattedKey;
    }

Calling the mothod like this

formatString("ABCDEFGHIJKLMNOPQRST", "-", 4)

Would result in the return string as this

ABCD-EFGH-IJKL-MNOP-QRST

Solution 13 - C#

I am more than late with my answer but you can use this one:

    static string PutLineBreak(string str, int split)
    {
        for (int a = 1; a <= str.Length; a++)
        {
            if (a % split == 0)
                str = str.Insert(a, "\n");
        }

        return str;
    }

Solution 14 - C#

For every 1 character, you could do this one-liner:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAbdur RahimView Question on Stackoverflow
Solution 1 - C#JoeyView Answer on Stackoverflow
Solution 2 - C#Sergey KalinichenkoView Answer on Stackoverflow
Solution 3 - C#AlexView Answer on Stackoverflow
Solution 4 - C#Wolf5370View Answer on Stackoverflow
Solution 5 - C#Johan LarssonView Answer on Stackoverflow
Solution 6 - C#David PedenView Answer on Stackoverflow
Solution 7 - C#driisView Answer on Stackoverflow
Solution 8 - C#C.M.View Answer on Stackoverflow
Solution 9 - C#Hiren PatelView Answer on Stackoverflow
Solution 10 - C#Mateusz PuwałowskiView Answer on Stackoverflow
Solution 11 - C#DustyView Answer on Stackoverflow
Solution 12 - C#RajanView Answer on Stackoverflow
Solution 13 - C#GameChangerView Answer on Stackoverflow
Solution 14 - C#Ma DudeView Answer on Stackoverflow