11

Suppose I have a string with the text: "THIS IS A TEST". How would I split it every n characters? So if n was 10, then it would display:

"THIS IS A "
"TEST"

..you get the idea. The reason is because I want to split a very big line into smaller lines, sort of like word wrap. I think I can use string.Split() for this, but I have no idea how and I'm confused.

Any help would be appreciated.

dnclem
  • 2,818
  • 15
  • 46
  • 64
  • 1
    possible duplicate of [C# Split a string into equal chunks each of size 4](http://stackoverflow.com/questions/1450774/c-sharp-split-a-string-into-equal-chunks-each-of-size-4) – Rune FS Oct 14 '11 at 13:42
  • Does this answer your question? [Splitting a string into chunks of a certain size](https://stackoverflow.com/questions/1450774/splitting-a-string-into-chunks-of-a-certain-size) – Magnetron Jul 11 '22 at 19:05
  • Does this answer your question? [Splitting a string / number every Nth Character / Number?](https://stackoverflow.com/questions/4133377/splitting-a-string-number-every-nth-character-number) – StayOnTarget Sep 26 '22 at 14:54

6 Answers6

26

Let's borrow an implementation from my answer on code review. This inserts a line break every n characters:

public static string SpliceText(string text, int lineLength) {
  return Regex.Replace(text, "(.{" + lineLength + "})", "$1" + Environment.NewLine);
}

Edit:
To return an array of strings instead:

public static string[] SpliceText(string text, int lineLength) {
  return Regex.Matches(text, ".{1," + lineLength + "}").Cast<Match>().Select(m => m.Value).ToArray();
}
Community
  • 1
  • 1
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
4

Maybe this can be used to handle efficiently extreme large files :

public IEnumerable<string> GetChunks(this string sourceString, int chunkLength)
{  
    using(var sr = new StringReader(sourceString))
    {
        var buffer = new char[chunkLength];
        int read;
        while((read= sr.Read(buffer, 0, chunkLength)) == chunkLength)
        {
            yield return new string(buffer, 0, read);
        }        
    }
}

Actually, this works for any TextReader. StreamReader is the most common used TextReader. You can handle very large text files (IIS Log files, SharePoint Log files, etc) without having to load the whole file, but reading it line by line.

Mikescher
  • 875
  • 2
  • 16
  • 35
Steve B
  • 36,818
  • 21
  • 101
  • 174
  • 1
    The general idea is good but isn't this approach missing the last characters if `source.Length` is not a multiple of `chunkLength`? – Jack Miller Jul 18 '21 at 05:08
  • If you want to read all string(include last string which length is less than `chunkLength`),just use this condition:`while ((read = sr.Read(buffer, 0, chunkLength)) !=0)` – 我零0七 Sep 24 '21 at 02:12
2

You should be able to use a regex for this. Here is an example:

//in this case n = 10 - adjust as needed
List<string> groups = (from Match m in Regex.Matches(str, ".{1,10}") 
                       select m.Value).ToList();

string newString = String.Join(Environment.NewLine, lst.ToArray());

Refer to this question for details:
Splitting a string into chunks of a certain size

Community
  • 1
  • 1
James Johnson
  • 45,496
  • 8
  • 73
  • 110
1

Coming back to this after doing a code review, there's another way of doing the same without using Regex

public static IEnumerable<string> SplitText(string text, int length)
{
    for (int i = 0; i < text.Length; i += length)
    {
        yield return text.Substring(i, Math.Min(length, text.Length - i));  
    }
}
canton7
  • 37,633
  • 3
  • 64
  • 77
1

Probably not the most optimal way, but without regex:

string test = "my awesome line of text which will be split every n characters";
int nInterval = 10;
string res = String.Concat(test.Select((c, i) => i > 0 && (i % nInterval) == 0 ? c.ToString() + Environment.NewLine : c.ToString()));
Peter
  • 14,221
  • 15
  • 70
  • 110
0

Some code that I just wrote:

string[] SplitByLength(string line, int len, int IsB64=0) {

    int i;

    if (IsB64 == 1) {
        // Only Allow Base64 Line Lengths without '=' padding
        int mod64 = (len % 4);
        if (mod64 != 0) {
            len = len + (4 - mod64);
        }
    }

    int parts = line.Length / len;
    int frac  = line.Length % len;
    int extra = 0;
    if (frac != 0) {
        extra = 1;
    }
   
    string[] oline = new string[parts + extra];
   
    for(i=0; i < parts; i++) {
        oline[i] = line.Substring(0, len);
        line     = line.Substring(len);
    }
   
    if (extra == 1) {
        oline[i] = line;
    }
    return oline;
}

string CRSplitByLength(string line, int len, int IsB64 = 0)
{
    string[] lines = SplitByLength(line, len, IsB64);
    return string.Join(System.Environment.NewLine, lines);
}

string m = "1234567890abcdefghijklmnopqrstuvwxhyz";

string[] r = SplitByLength(m, 6, 0);

foreach (string item in r) {
    Console.WriteLine("{0}", item);
}

Bimo
  • 5,987
  • 2
  • 39
  • 61