String input = \"THESE TERMS AND CONDITIONS OF SERVICE (the Terms) ARE A LEGAL AND BINDING AGREEMENT BETWEEN YOU AND NATIONAL GEOGRAPHIC governing your use of this s
I have recently written a few methods to do this that, if no whitespace characters are present in one of the lines, opts for splitting on other non-alphanumeric characters prior to resorting to a mid-word split.
Here is how it turned out for me:
(Uses the lastIndexOfRegex()
methods I posted here.)
/**
* Indicates that a String search operation yielded no results.
*/
public static final int NOT_FOUND = -1;
/**
* Version of lastIndexOf that uses regular expressions for searching.
* By Tomer Godinger.
*
* @param str String in which to search for the pattern.
* @param toFind Pattern to locate.
* @return The index of the requested pattern, if found; NOT_FOUND (-1) otherwise.
*/
public static int lastIndexOfRegex(String str, String toFind)
{
Pattern pattern = Pattern.compile(toFind);
Matcher matcher = pattern.matcher(str);
// Default to the NOT_FOUND constant
int lastIndex = NOT_FOUND;
// Search for the given pattern
while (matcher.find())
{
lastIndex = matcher.start();
}
return lastIndex;
}
/**
* Finds the last index of the given regular expression pattern in the given string,
* starting from the given index (and conceptually going backwards).
* By Tomer Godinger.
*
* @param str String in which to search for the pattern.
* @param toFind Pattern to locate.
* @param fromIndex Maximum allowed index.
* @return The index of the requested pattern, if found; NOT_FOUND (-1) otherwise.
*/
public static int lastIndexOfRegex(String str, String toFind, int fromIndex)
{
// Limit the search by searching on a suitable substring
return lastIndexOfRegex(str.substring(0, fromIndex), toFind);
}
/**
* Breaks the given string into lines as best possible, each of which no longer than
* <code>maxLength</code> characters.
* By Tomer Godinger.
*
* @param str The string to break into lines.
* @param maxLength Maximum length of each line.
* @param newLineString The string to use for line breaking.
* @return The resulting multi-line string.
*/
public static String breakStringToLines(String str, int maxLength, String newLineString)
{
StringBuilder result = new StringBuilder();
while (str.length() > maxLength)
{
// Attempt to break on whitespace first,
int breakingIndex = lastIndexOfRegex(str, "\\s", maxLength);
// Then on other non-alphanumeric characters,
if (breakingIndex == NOT_FOUND) breakingIndex = lastIndexOfRegex(str, "[^a-zA-Z0-9]", maxLength);
// And if all else fails, break in the middle of the word
if (breakingIndex == NOT_FOUND) breakingIndex = maxLength;
// Append each prepared line to the builder
result.append(str.substring(0, breakingIndex + 1));
result.append(newLineString);
// And start the next line
str = str.substring(breakingIndex + 1);
}
// Check if there are any residual characters left
if (str.length() > 0)
{
result.append(str);
}
// Return the resulting string
return result.toString();
}
Best : use Apache Commons Lang :
org.apache.commons.lang.WordUtils
/**
* <p>Wraps a single line of text, identifying words by <code>' '</code>.</p>
*
* <p>New lines will be separated by the system property line separator.
* Very long words, such as URLs will <i>not</i> be wrapped.</p>
*
* <p>Leading spaces on a new line are stripped.
* Trailing spaces are not stripped.</p>
*
* <pre>
* WordUtils.wrap(null, *) = null
* WordUtils.wrap("", *) = ""
* </pre>
*
* @param str the String to be word wrapped, may be null
* @param wrapLength the column to wrap the words at, less than 1 is treated as 1
* @return a line with newlines inserted, <code>null</code> if null input
*/
public static String wrap(String str, int wrapLength) {
return wrap(str, wrapLength, null, false);
}