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