2013-03-08 40 views
7

Tôi có một chuỗi dài và tôi muốn vừa với nó trong một lĩnh vực nhỏ. Để đạt được điều đó, tôi chia chuỗi thành các dòng trên khoảng trắng. Thuật toán diễn ra như sau:Tách văn bản thành các dòng có chiều dài tối đa

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

Nhưng điều này bị ngắt khi có từ ngắn, theo sau là từ dài hơn. "foo howcomputerwork" với độ dài tối đa là 16 không phá vỡ, nhưng tôi muốn nó. Một ý nghĩ tôi đã mong chờ được thấy nơi khoảng trống tiếp theo xảy ra, nhưng tôi không chắc liệu điều đó có dẫn đến một vài dòng nhất có thể không.

+0

Bạn có muốn * ít nhất * n ký tự trong một dòng hoặc * nhiều nhất * không? Bởi vì nếu bạn muốn * nhiều nhất * n ký tự bạn cần phải làm việc theo cách của bạn trở lại từ ký tự thứ n đến khoảng trắng. Và nếu bất cứ lúc nào có một từ với nhiều hơn n ký tự, bạn đang say.^_ ^; – Corak

+0

@Corak "Phân tách văn bản thành các dòng có ** độ dài ** tối đa", không có nghĩa là * nhiều nhất *? – Nolonar

+0

@Nolonar có, nhưng mã ngụ ý * ít nhất *, vì vậy tôi không chắc chắn. – Corak

Trả lời

1

Kiểm tra các nội dung của nhân vật trước bằng văn bản cho người xây dựng chuỗi và or nó với số lượng hiện tại:

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

sử dụng tuyệt vời của xây dựng chuỗi, nó là cần thiết khi concatinating nhiều dây với nhau. có vẻ như nó sẽ thêm một dòng mới cho mỗi từ trong văn bản. –

+0

Mã này đặt mỗi từ trên dòng mới, bất kể kết thúc dòng (dựa trên maxCharsInLine) hay không. –

+0

@PR Theo câu hỏi được hỏi: 'Tôi ngắt chuỗi thành dòng trên khoảng trắng' ngụ ý rằng anh ấy ngắt dòng ở khoảng trắng (và số ký tự) – Moop

6

Thưởng thức!

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

Lưu ý rằng splitOnCharactersmaxStringLength có thể được lưu trong khu vực cài đặt người dùng của ứng dụng.

+0

Bài đăng gốc đã được kiểm tra và làm việc, không chắc chắn nếu @DIMI có cơ hội thử nghiệm các chỉnh sửa của mình nhưng tôi có cảm giác IIRC (từ 2 năm trước = P), bạn cần phải tiêm 1 ký tự trên mỗi dòng bằng phương pháp này. –

+1

Hey :) Tôi sử dụng cùng một mã. Tôi chỉ thực hiện nó như một phần mở rộng bởi vì nó là loại phổ biến nhất của việc sử dụng cho các phương pháp như chia thành mảng hoặc chia thành các dòng. Và câu trả lời của bạn là tuyệt vời vì vậy tôi đã +1, người đàn ông. –

0

cập nhật mã một chút, @ dead.rabit chuyển sang vòng lặp đôi khi.

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(); 
    } 
Các vấn đề liên quan