如何在不打断单词的情况下按字符和行长打断字符串?

How to break string by character and line length, without breaking words?

我想按字符和行的长度来打断一个长字符串,而不打断单词。 在我的字符串中,我使用“|”作为我的分隔符,每一行都不能以分隔符结尾。我需要在“|”处打断,不要打断单词。

我尝试了以下方法,它查看最大行长度,并确保一切都合适。现在我必须用“|”来实现分隔字符而不中断行长度检查。

int partLength = 35;
string sentence = "Silver badges are awarded for longer term goals. Silver badges are uncommon.";
string[] words = sentence.Split(' ');
var parts = new Dictionary<int, string>();
string part = string.Empty;
int partCounter = 0;

        foreach (var word in words)
        {
            if (part.Length + word.Length < partLength)
            {
                part += string.IsNullOrEmpty(part) ? word : " " + word;
            }
            else
            {
                parts.Add(partCounter, part);
                part = word;
                partCounter++;
            }
        }
        parts.Add(partCounter, part);
        foreach (var item in parts)
        {
            Console.WriteLine(item.Value);
        }

我尝试了以下按字符“|”打破:

string sentence = "The dog had a bone | a ball | and other toys.";
        char charToTrim = '|';
        string[] words = sentence.Split();
        foreach (string word in words)
           Console.WriteLine(word.TrimEnd(charToTrim));

这将在新行上打印所有单词,这是不正确的。 所以在长文本中,我需要查看最大行长度,以及分隔符“|”。单词必须在行内匹配,但新行不能以“|”结尾。

所以以下是正确的:

Item 1 | Item 2 | Item 3 | Item 4
| Item 5 | Etc

但以下是错误的:

Item 1 | Item 2 | Item 3 | Item 4 |
Item 5 | Etc

您不能使用 | 拆分字符串,因为您会丢失有关它们在原始字符串中的位置的信息。此外,您将无法使用 foreach 执行此操作,因为在计算下一个字符串的长度时需要向前看。使用您的原始代码,您可以这样做:

int partLength = 35;
string sentence = "Item 1 | Item 2 | Item 3 | Item 4 | Item 5 | Etc";
string[] words = sentence.Split(' ');
var parts = new Dictionary<int, string>();
string part = string.Empty;
int partCounter = 0;

for(int i = 0; i < words.Count(); i++)
{
    var newLength = part.Length + words[i].Length;

    if(words[i] == "|" && i + 1 < words.Count())
    {
        newLength += words[i + 1].Length;
    }

    if (newLength < partLength)
    {
        part += string.IsNullOrEmpty(part) ? words[i] : " " + words[i];
    }
    else
    {
        parts.Add(partCounter, part);
        part = words[i];
        partCounter++;
    }
}
parts.Add(partCounter, part);
foreach (var item in parts)
{
    Console.WriteLine(item.Value);
}

我们仍然在 space 上拆分,但我们使用 for 循环来遍历字符串。在我们检查当前单词是否适合之前,我们需要检查它是否是 |。如果是,则也添加下一个单词(如果存在)。这应该会产生您正在寻找的输出。

修改您的示例(并遵循您的初始方法)我能够这样做(我的想法是再看一个词,以防我们遇到分隔符):

int partLength = 15;
string sentence = "Item1 | Item2 | Item3 | Item4 | Item5 | Item6 | Item7 |";
string[] words = sentence.Split(' ');
var parts = new List<string>();
var partBuilder = new StringBuilder(partLength);
int partCounter = 0;

for (int i = 0; i < words.Length; i++)
{
    var word = words[i];
    var nextWord = (i < words.Length - 1) 
        ? words[i + 1]
        : null;
    var lengthToCheck = 
        word == "|" && nextWord != null
            ? word.Length + nextWord.Length
            : word.Length;

    if (partBuilder.Length + lengthToCheck < partLength)
    {
        if (partBuilder.Length > 0)
            partBuilder.Append(" ");
        partBuilder.Append(word);
    }
    else
    {
        parts.Add(partBuilder.ToString());
        partBuilder.Clear();
        partBuilder.Append(word);
        partCounter++;
    }
}
parts.Add(partBuilder.ToString());

foreach (var item in parts)
{
    Console.WriteLine(item);
}

输出为:

Item1 | Item2
| Item3 | Item4
| Item5 | Item6
| Item7 |

我还用 StringBuilder 替换了字符串连接,这被认为是连接大量字符串的最佳实践。

而且我仍然觉得通过逐个字符地移动字符串更容易解决这个问题。