【问题标题】:How to break string by character and line length, without breaking words?如何在不中断单词的情况下按字符和行长中断字符串?
【发布时间】:2020-03-07 14:50:13
【问题描述】:

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

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

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));

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

所以下面是正确的:

第 1 项 |项目 2 |项目 3 |项目 4
|项目 5 |等等

但以下是不正确的:

第 1 项 |项目 2 |项目 3 |项目 4 |
项目 5 |等等

【问题讨论】:

  • 如果您在原始解决方案中为 Split 方法提供多个字符怎么办?它接受 char[],所以你可以这样写:string[] words = sentence.Split(new [] { ' ', '|' });
  • 但是如果我这样做,它总是会在“|”上分割,即使还有更多单词的空间
  • 那么我不清楚你到底想要什么。是否只是修剪“|”从线路末端?或者你想摆脱“|”完全在文本中?
  • 我想在行中没有更多空间时中断(因为代码中设置了最大行长度)。词不能断。但是,一行绝不能以“|”结尾
  • 因此,当特定单词没有更多空间时,如果有分隔符“|”即使上一行有空间,它也必须转到新行

标签: c# string split break line-breaks


【解决方案1】:

修改您的示例(并遵循您的初始方法)我能够这样做(想法是在遇到分隔符的情况下再看一个单词):

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,这被认为是串联大量字符串时的最佳实践。

而且我仍然有勇气通过逐个字符地遍历字符串来解决这个问题。

【讨论】:

    【解决方案2】:

    您不能使用| 拆分字符串,因为您会丢失有关它们在原始字符串中的位置的信息。此外,您将无法使用 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);
    }
    
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-04
      • 1970-01-01
      • 2011-10-02
      • 1970-01-01
      • 1970-01-01
      • 2020-11-19
      • 1970-01-01
      相关资源
      最近更新 更多