Divide the long line into 60 characters with long lines, but don't break the words

There must be a better way to do this. I just want to split the long string into 60 characters, but not break the words. Thus, it should not contain up to 60 characters, but should be less than 60.

The code below is what I have and it works, but I think this is the best way. Is anyone

Changed to use StringBuilder and fixed the problem of deleting duplicate words. Also don't want to use regex because I think it will be less efficient than what I have.

public static List<String> FormatMe(String Message) { Int32 MAX_WIDTH = 60; List<String> Line = new List<String>(); String[] Words; Message = Message.Trim(); Words = Message.Split(" ".ToCharArray()); StringBuilder s = new StringBuilder(); foreach (String Word in Words) { s.Append(Word + " "); if (s.Length > MAX_WIDTH) { s.Replace(Word, "", 0, s.Length - Word.Length); Line.Add(s.ToString().Trim()); s = new StringBuilder(Word + " "); } } if (s.Length > 0) Line.Add(s.ToString().Trim()); return Line; } 

thanks

+4
source share
7 answers

Try the following:

 const Int32 MAX_WIDTH = 60; string text = "..."; List<string> lines = new List<string>(); StringBuilder line = new StringBuilder(); foreach(Match word in Regex.Matches(text, @"\S+", RegexOptions.ECMAScript)) { if (word.Value.Length + line.Length + 1 > MAX_WIDTH) { lines.Add(line.ToString()); line.Length = 0; } line.Append(String.Format("{0} ", word.Value)); } if (line.Length > 0) line.Append(word.Value); 

Please also check this: How to use regex to add linefeeds?

0
source

Another example (now TESTED), very similar to Keith's approach :

 static void Main(string[] args) { const Int32 MAX_WIDTH = 60; int offset = 0; string text = Regex.Replace(File.ReadAllText("oneline.txt"), @"\s{2,}", " "); List<string> lines = new List<string>(); while (offset < text.Length) { int index = text.LastIndexOf(" ", Math.Min(text.Length, offset + MAX_WIDTH)); string line = text.Substring(offset, (index - offset <= 0 ? text.Length : index) - offset ); offset += line.Length + 1; lines.Add(line); } } 

I ran this on this file with all line breaks manually replaced by "".

+6
source

Inside the regular expression, the Match Evaluator function (anonymous method) does the grunt job and saves newlines in StringBuilder. We do not use the return value of the Regex.Replace method because we simply use the Match Evaluator function as a function to perform line breaks inside a regular expression call - just for that, because I think it's cool.

 using System; using System.Text; using System.Text.RegularExpressions; 

strInput is what you want to convert.

 int MAX_LEN = 60; StringBuilder sb = new StringBuilder(); int bmark = 0; //bookmark position Regex.Replace(strInput, @".*?\b\w+\b.*?", delegate(Match m) { if (m.Index - bmark + m.Length + m.NextMatch().Length > MAX_LEN || m.Index == bmark && m.Length >= MAX_LEN) { sb.Append(strInput.Substring(bmark, m.Index - bmark + m.Length).Trim() + Environment.NewLine); bmark = m.Index + m.Length; } return null; }, RegexOptions.Singleline); if (bmark != strInput.Length) // last portion sb.Append(strInput.Substring(bmark)); string strModified = sb.ToString(); // get the real string from builder 

It is also worth noting that the second condition in the if expression in the Match m.Index == bmark && m.Length >= MAX_LEN implied as an exceptional condition if the word is longer than 60 characters (or longer than the specified maximum length) - it will not be broken here, but just saved on one line by itself - I think you might want to create a second formula for this condition in the real world for transferring it or something else.

+1
source

I would start by preserving the length of the original string. Then start back and just subtract, since the probability that I will get below 60 is faster, starting from the last word and coming back than building up.

Once I know how long, just use a StringBuilder and create a string for a new line.

0
source
 List<string> lines = new List<string>(); while (message.Length > 60) { int idx = message.LastIndexOf(' ', 60); lines.Add(message.Substring(0, idx)); message = message.Substring(idx + 1, message.Length - (idx + 1)); } lines.Add(message); 

You may need to change the bit to handle multiple spaces, words s> 60 characters in them, ...

0
source

Other...

 public static string SplitLongWords(string text, int maxWordLength) { var reg = new Regex(@"\S{" + (maxWordLength + 1) + ",}"); bool replaced; do { replaced = false; text = reg.Replace(text, (m) => { replaced = true; return m.Value.Insert(maxWordLength, " "); }); } while (replaced); return text; } 
0
source

I tried the original solution and found that it does not quite work. I changed it a bit to make it work. Now it works for me and solves the problem that I had. Thank you Jim.

 public static List<String> FormatMe(String message) { int maxLength = 10; List<String> Line = new List<String>(); String[] words; message = message.Trim(); words = message.Split(" ".ToCharArray()); StringBuilder sentence = new StringBuilder(); foreach (String word in words) { if((sentence.Length + word.Length) <= maxLength) { sentence.Append(word + " "); } else { Line.Add(sentence.ToString().Trim()); sentence = new StringBuilder(word + " "); } } if (sentence.Length > 0) Line.Add(sentence.ToString().Trim()); return Line; } private void btnSplitText_Click(object sender, EventArgs e) { List<String> Line = new List<string>(); string message = "The quick brown fox jumps over the lazy dog."; Line = FormatMe(message); } 
0
source

All Articles