如何在不打断单词的情况下按字符和行长打断字符串?
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 替换了字符串连接,这被认为是连接大量字符串的最佳实践。
而且我仍然觉得通过逐个字符地移动字符串更容易解决这个问题。
我想按字符和行的长度来打断一个长字符串,而不打断单词。 在我的字符串中,我使用“|”作为我的分隔符,每一行都不能以分隔符结尾。我需要在“|”处打断,不要打断单词。
我尝试了以下方法,它查看最大行长度,并确保一切都合适。现在我必须用“|”来实现分隔字符而不中断行长度检查。
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 替换了字符串连接,这被认为是连接大量字符串的最佳实践。
而且我仍然觉得通过逐个字符地移动字符串更容易解决这个问题。