Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Splitting a string / number every Nth Character / Number?

I need to split a number into even parts for example:

32427237 needs to become 324 272 37
103092501 needs to become 103 092 501

How does one go about splitting it and handling odd number situations such as a split resulting in these parts e.g. 123 456 789 0?

like image 583
RoguePlanetoid Avatar asked Nov 09 '10 11:11

RoguePlanetoid


People also ask

How do you split a string after a specific number of characters in Python?

Use range() function and slicing notation to split string by a number of characters in Python.

How do you split a string at a certain character?

To split a string with specific character as delimiter in Java, call split() method on the string object, and pass the specific character as argument to the split() method. The method returns a String Array with the splits as elements in the array.


3 Answers

If you have to do that in many places in your code you can create a fancy extension method:

static class StringExtensions {

  public static IEnumerable<String> SplitInParts(this String s, Int32 partLength) {
    if (s == null)
      throw new ArgumentNullException(nameof(s));
    if (partLength <= 0)
      throw new ArgumentException("Part length has to be positive.", nameof(partLength));

    for (var i = 0; i < s.Length; i += partLength)
      yield return s.Substring(i, Math.Min(partLength, s.Length - i));
  }

}

You can then use it like this:

var parts = "32427237".SplitInParts(3);
Console.WriteLine(String.Join(" ", parts));

The output is 324 272 37 as desired.

When you split the string into parts new strings are allocated even though these substrings already exist in the original string. Normally, you shouldn't be too concerned about these allocations but using modern C# you can avoid this by altering the extension method slightly to use "spans":

public static IEnumerable<ReadOnlyMemory<char>> SplitInParts(this String s, Int32 partLength)
{
    if (s == null)
        throw new ArgumentNullException(nameof(s));
    if (partLength <= 0)
        throw new ArgumentException("Part length has to be positive.", nameof(partLength));

    for (var i = 0; i < s.Length; i += partLength)
        yield return s.AsMemory().Slice(i, Math.Min(partLength, s.Length - i));
}

The return type is changed to public static IEnumerable<ReadOnlyMemory<char>> and the substrings are created by calling Slice on the source which doesn't allocate.

Notice that if you at some point have to convert ReadOnlyMemory<char> to string for use in an API a new string has to be allocated. Fortunately, there exists many .NET Core APIs that uses ReadOnlyMemory<char> in addition to string so the allocation can be avoided.

like image 102
Martin Liversage Avatar answered Oct 13 '22 04:10

Martin Liversage


You could use a simple for loop to insert blanks at every n-th position:

string input = "12345678";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.Length; i++)
{
    if (i % 3 == 0)
        sb.Append(' ');
    sb.Append(input[i]);
}
string formatted = sb.ToString();
like image 10
Dirk Vollmar Avatar answered Oct 13 '22 03:10

Dirk Vollmar


One very simple way to do this (not the most efficient, but then not orders of magnitude slower than the most efficient).

    public static List<string> GetChunks(string value, int chunkSize)
    {
        List<string> triplets = new List<string>();
        while (value.Length > chunkSize)
        {
            triplets.Add(value.Substring(0, chunkSize));
            value = value.Substring(chunkSize);
        }
        if (value != "")
            triplets.Add(value);
        return triplets;
    }

Heres an alternate

    public static List<string> GetChunkss(string value, int chunkSize)
    {
        List<string> triplets = new List<string>();
        for(int i = 0; i < value.Length; i += chunkSize)
            if(i + chunkSize > value.Length)
                triplets.Add(value.Substring(i));
            else
                triplets.Add(value.Substring(i, chunkSize));

        return triplets;
    }
like image 7
Binary Worrier Avatar answered Oct 13 '22 03:10

Binary Worrier