2013-03-08 7 views
7

長い文字列があり、小さなフィールドに収めたいのですが。これを実現するために、文字列を空白の行に分割します。アルゴリズムは次のようになります。テキストを最大長の行に分割する

public static string BreakLine(string text, int maxCharsInLine) 
    { 
     int charsInLine = 0; 
     StringBuilder builder = new StringBuilder(); 
     for (int i = 0; i < text.Length; i++) 
     { 
      char c = text[i]; 
      builder.Append(c); 
      charsInLine++; 

      if (charsInLine >= maxCharsInLine && char.IsWhiteSpace(c)) 
      { 
       builder.AppendLine(); 
       charsInLine = 0; 
      } 
     } 
     return builder.ToString(); 
    } 

ただし、短い単語が続くとこれが壊れ、長い単語が続きます。最大長16の "foo howcomputerwork"は中断しませんが、私はそれを望みます。私が思っていたことは、次の空白がどこにあるのか楽しみにしていましたが、できるだけ少ないラインができるかどうかはわかりません。

+0

少なくとも* n文字以上の行を*または最大*にしたいですか?もしあなたが*多くても* n文字で*必要ならば、n番目の文字から空白に戻って作業する必要があるからです。そして、いつでもn文字以上の単語があれば、あなたは嫌われます。^_ ^; – Corak

+0

@Corak "テキストを**最大**長さの行に分割する"とは、*であっても最大*を意味しません。 – Nolonar

+0

@Nolonarはい、コードは少なくとも*を意味するので、わかりませんでした。 – Corak

答えて

1

現在のカウントでor、それを文字列ビルダに書き込む前に、文字の内容を確認し、:

public static string BreakLine(string text, int maxCharsInLine) 
    { 
     int charsInLine = 0; 
     StringBuilder builder = new StringBuilder(); 
     for (int i = 0; i < text.Length; i++) 
     { 
      char c = text[i]; 
      if (char.IsWhiteSpace(c) || charsInLine >= maxCharsInLine) 
      { 
       builder.AppendLine(); 
       charsInLine = 0; 
      } 
      else 
      { 
       builder.Append(c); 
       charsInLine++;      
      } 
     } 
     return builder.ToString(); 
    } 
+0

文字列ビルダの優れた使い方は、この多くの文字列を一緒にconcatinatingするときに必要です。しかし、それはテキストのすべての単語のための新しい行を追加するように見えます。 –

+0

このコードは、行の終わり(maxCharsInLineに基づく)に関係なく、新しい行に各単語を配置します。 –

+0

@PR質問:「文字列を空白の行に分割する」とは、空白(および文字数)で行を分割することを意味します。 – Moop

6

お楽しみください!

public static string SplitToLines(string text, char[] splitOnCharacters, int maxStringLength) 
{ 
    var sb = new StringBuilder(); 
    var index = 0; 

    while (text.Length > index) 
    { 
     // start a new line, unless we've just started 
     if (index != 0) 
      sb.AppendLine(); 

     // get the next substring, else the rest of the string if remainder is shorter than `maxStringLength` 
     var splitAt = index + maxStringLength <= text.Length 
      ? text.Substring(index, maxStringLength).LastIndexOfAny(splitOnCharacters) 
      : text.Length - index; 

     // if can't find split location, take `maxStringLength` characters 
     splitAt = (splitAt == -1) ? maxStringLength : splitAt; 

     // add result to collection & increment index 
     sb.Append(text.Substring(index, splitAt).Trim()); 
     index += splitAt; 
    } 

    return sb.ToString(); 
} 

splitOnCharactersmaxStringLengthアプリのユーザー設定領域に保存することができることに注意してください。

+0

@DIMIが編集内容をテストする機会があったかどうかはわかりませんが、IIRC(2年前から= P)の方がこのメソッドを使ってすべての行に1文字を注入する必要があります。 –

+1

ちょっと:)私は同じコードを使用します。私は、配列への分割や線分への分割のようなメソッドのための最も一般的な使い方であるため、拡張のように実装しました。あなたの答えは素晴らしいので+1しました。 –

0

コードを少し更新すると、@ dead.rabitはいつかループします。

public static string SplitToLines(string text,char[] splitanyOf, int maxStringLength) 
    {    
     var sb = new System.Text.StringBuilder(); 
     var index = 0; 
     var loop = 0; 
     while (text.Length > index) 
     { 
      // start a new line, unless we've just started 
      if (loop != 0) 
      { 
       sb.AppendLine(); 
      } 

      // get the next substring, else the rest of the string if remainder is shorter than `maxStringLength` 
      var splitAt = 0; 
      if (index + maxStringLength <= text.Length) 
      { 
       splitAt = text.Substring(index, maxStringLength).LastIndexOfAny(splitanyOf); 
      } 
      else 
      { 
       splitAt = text.Length - index; 
      } 

      // if can't find split location, take `maxStringLength` characters 
      if (splitAt == -1 || splitAt == 0) 
      { 
       splitAt = text.IndexOfAny(splitanyOf, maxStringLength); 
      } 

      // add result to collection & increment index 
      sb.Append(text.Substring(index, splitAt).Trim()); 
      if(text.Length > splitAt) 
      { 
       text = text.Substring(splitAt + 1).Trim(); 
      } 
      else 
      { 
       text = string.Empty; 
      } 
      loop = loop + 1; 
     } 

     return sb.ToString(); 
    } 
関連する問題