【问题标题】:How do I break a long String in c# without breaking a words如何在不破坏单词的情况下在 c# 中破坏长字符串
【发布时间】:2021-09-03 23:25:09
【问题描述】:

我想在 c# 中打断一个长字符串而不打断一个单词
示例:S AAA BBBBBBB CC DDDDDD V 7 计数中断字符:

S AAA
BBBBBBB
CC 
DDDDDD 
V 

我该怎么做?

【问题讨论】:

  • 你应该根据什么标准选择S AAA作为一个词?
  • 为什么要指定这么多 c# 版本?你想分别回复每一个?
  • 我在这里看不到模式。当你说“打破 7 个字符”时,你永远不会得到你想要的结果。例如,如果您在 7 个字符数上打断第一个单词,您将得到 "S AAA B" 而不是 "S AAA ""CC" 不符合您的规则。

标签: c#


【解决方案1】:
string inputStr = "S AAA BBBBBBB CC DDDDDD V ";
int maxWordLength = 7;
char separator = ' ';

string[] splitted = inputStr.Split(new[]{separator}, StringSplitOptions.RemoveEmptyEntries);

var joined = new Stack<string>();
joined.Push(splitted[0]);

foreach (var str in splitted.Skip(1))
{
    var strFromStack = joined.Pop();
    var joindedStr = strFromStack + separator + str;
    if(joindedStr.Length > maxWordLength)
    {
        joined.Push(strFromStack);
        joined.Push(str);
    }
    else
    {
        joined.Push(joindedStr);
    }
}   
var result = joined.Reverse().ToArray();

Console.WriteLine ("number of words: {0}", result.Length);

Console.WriteLine( string.Join(Environment.NewLine, result) );

打印:

number of words: 5
S AAA
BBBBBBB
CC
DDDDDD
V

【讨论】:

  • 这不是 OP 想要的输出。第一个“单词”应该是S AAA
  • @ChrisF @anurag 有问题有一个声明without breaking a wordsS AAA 是一个词吗?
  • 我可能是错的,但从我从他的问题和预期输出中了解到,他想用空格字符分割字符串,然后如果连续单词的组合少于 7 个字符,那么它们应该是作为一个单一的令牌。因此是“S AAA”令牌。
  • @mematei 用空格分割字符串 那么S AAA是一个词吗?
  • @Ilya Ivanov 请阅读整个评论,我将强调您需要查看的部分“如果连续单词的组合少于 7 个字符,则应将它们视为单个标记”,这是我从“7 Count Breaking Character”中得出的
【解决方案2】:

这是一个利用正则表达式功能的更短的解决方案。

string input = "S AAA BBBBBBB CC DDDDDD V";

// Match up to 7 characters with optional trailing whitespace, but only on word boundaries
string pattern = @"\b.{1,7}\s*\b";

var matches = Regex.Matches(input, pattern);

foreach (var match in matches)
{
    Debug.WriteLine(match.ToString());
}

【讨论】:

    【解决方案3】:

    如果我正确理解了您的问题,这就可以解决问题。递归实现会更酷,但尾递归在 C# 中太糟糕了:)

    也可以用 yield 和 IEnumerable&lt;string&gt; 来实现。

    string[] splitSpecial(string words, int lenght)
    {
      // The new result, will be turned into string[]
      var newSplit = new List<string>();
      // Split on normal chars, ie newline, space etc
      var splitted = words.Split();
      // Start out with null
      string word = null;
    
      for (int i = 0; i < splitted.Length; i++)
      {
          // If first word, add
          if (word == null)
          {
              word = splitted[i];
          }
          // If too long, add
          else if (splitted[i].Length + 1 + word.Length > lenght)
          {
              newSplit.Add(word);
              word = splitted[i];
          }
          // Else, concatenate and go again
          else
          {
              word += " " + splitted[i];
          }
      }
      // Flush what we have left, ie the last word
      newSplit.Add(word);
    
      // Convert into string[] (a requirement?)
      return newSplit.ToArray();
    }
    

    【讨论】:

      【解决方案4】:

      为什么不试试正则表达式?

      (?:^|\s)(?:(.{1,7}|\S{7,}))(?=\s|$)
      

      并使用所有捕获。

      C#代码:

      var text = "S AAA BBBBBBB CC DDDDDD V";
      var matches = new Regex(@"(?:^|\s)(?:(.{1,7}|\S{7,}))(?=\s|$)").Matches(text).Cast<Match>().Select(x => x.Groups[1].Value).ToArray();
      foreach (var match in matches)
      {
          Console.WriteLine(match);
      }
      

      输出:

      S AAA
      BBBBBBB
      CC
      DDDDDD
      V
      

      【讨论】:

        【解决方案5】:
                string str = "S AAA BBBBBBB CC DDDDDD V";
                var words = str.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                StringBuilder sb = new StringBuilder();
                List<string> result = new List<string>();
                for (int i = 0; i < words.Length; ++i)
                {
                    if (sb.Length == 0)
                    {
                        sb.Append(words[i]);
                    }
                    else if (sb.Length + words[i].Length < 7)
                    {
                        sb.Append(' ');
                        sb.Append(words[i]);
                    }
                    else
                    {
                        result.Add(sb.ToString());
                        sb.Clear();
                        sb.Append(words[i]);
                    }
                }
                if (sb.Length > 0)
                {
                    result.Add(sb.ToString());
                }
        

        结果将包含:

        S AAA
        BBBBBBB
        CC
        DDDDDD
        V
        

        可以根据单词之间的分隔符是否应包含在 7 个字符中来调整谓词。

        【讨论】:

          【解决方案6】:

          这是给 HTML 文本添加换行符的方法:

          SplitLongText(string _SourceText, int _MaxRowLength) {

                  if (_SourceText.Length < _MaxRowLength)
                  {
                      return _SourceText;
                  }
                  else 
                  {
                      string _RowBreakText="";
                      int _CurrentPlace = 0;
                      while (_CurrentPlace < _SourceText.Length)
                      {
                          if (_SourceText.Length - _CurrentPlace < _MaxRowLength)
                          {
                              _RowBreakText += _SourceText.Substring(_CurrentPlace);
                              _CurrentPlace = _SourceText.Length; 
          
                          }
                          else
                          {
                              string _PartString = _SourceText.Substring(_CurrentPlace, _MaxRowLength);
                              int _LastSpace = _PartString.LastIndexOf(" ");
                              if (_LastSpace > 0)
                              {
                                  _RowBreakText += _PartString.Substring(0, _LastSpace) + "<br/>" + _PartString.Substring(_LastSpace, (_PartString.Length - _LastSpace));
                              }
                              else
                              {
                                  _RowBreakText += _PartString + "<br/>";
                              }
                              _CurrentPlace += _MaxRowLength;
                          }
          
                      }
                      return _RowBreakText;
          
                  }
          

          【讨论】:

            【解决方案7】:

            2021

            看看这个扩展方法,它使用递归

            public static string SubstringDontBreakWords(this string str, int maxLength)
            {
                return str.Length <= maxLength ? str : str.Substring(0, str.LastIndexOf(" ")).Trim().SubstringDontBreakWords(maxLength);
            }
            

            这样使用

            string text = "Hello friends";
            text.SubstringDontBreakWords(10)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-06-15
              • 1970-01-01
              • 2011-10-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多