简体   繁体   中英

C# - Split at 20 characters but not if it is in between a word

I want to split a string into smaller parts, not exceeding a string length of 20 characters.

The current code is able to split an input string into an array of strings of length 20. However, this could cut a word.

The current code is:

string[] Array;

StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.Length; i++)
{
  if (i % 20 == 0 && i != 0) {
    sb.Append('~');
  }
  sb.Append(input[i]);
}

Array =  sb.ToString().Split('~');

For an input of this: Hello. This is a string. Goodbye. Hello. This is a string. Goodbye. , the output would be ['Hello. This is a str', 'ing. Goodbye.'] ['Hello. This is a str', 'ing. Goodbye.'] ['Hello. This is a str', 'ing. Goodbye.'] .

However, I don't want the string to be cut if it's a word. That word should move to the next string in the array. How can I get the following output instead?

['Hello. This is a', 'string. Goodbye.']

First split your sentence on word-boundary:

var words = myString.Split();

Now concatenate words as long as not more than 20 characters are within your current line:

var lines = new List<string> { words[0] };
var lineNum = 0;
for(int i = 1; i < words.Length; i++)
{
    if(lines[lineNum].Length + words[i].Length + 1 <= 20)
        lines[lineNum] += " " + words[i];
    else
    {
        lines.Add(words[i]);
        lineNum++;
    }
}

Here is a fiddle for testing: https://dotnetfiddle.net/s0LrFC

Could be more elegant but this will split the string to lines of a maximum number of characters. The words will be kept together unless they exceed the given length.

    public static string[] SplitString(string input, int lineLen)
    {
        StringBuilder sb = new StringBuilder();
        string[] words = input.Split(' ');
        string line = string.Empty;
        string sp = string.Empty;
        foreach (string w in words)
        {
            string word = w;
            while (word != string.Empty)
            {
                if (line == string.Empty)
                {
                    while (word.Length >= lineLen)
                    {
                        sb.Append(word.Substring(0, lineLen) + "~");
                        word = word.Substring(lineLen);
                    }
                    if (word != string.Empty)
                        line = word;
                    word = string.Empty;
                    sp = " ";
                }
                else if (line.Length + word.Length <= lineLen)
                {
                    line += sp + word;
                    sp = " ";
                    word = string.Empty;
                }
                else
                {
                    sb.Append(line + "~");
                    line = string.Empty;
                    sp = string.Empty;
                }
            }
        }
        if (line != string.Empty)
            sb.Append(line);
        return sb.ToString().Split('~');
    }

To test:

string[] lines = SplitString("This is a test of the string splitter KGKGKJGKGHKJHJKJKHGJHGhghsjagsjasgajsgjahs yes!", 20);
foreach (string line in lines)
{
    Console.WriteLine(line);
}

Output:

This is a test of the
string splitter
KGKGKJGKGHKJHJKJKHGJ
HGhghsjagsjasgajsgja
hs yes!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM