I have a collection of strings. I need to be able to join the items in this collection into one string and afterwards split that string backwards and get original string collection.
Definitely I need to introduce a delimiter character for join/split operation. Given the fact that original strings can contain any characters, I also need to deal with delimiter escaping. My question is very simple - is there a Java class/library that can provide me required functionality out-of-the-box? Something like:
String join(String[] source, String delimiter, String escape);
String[] split(String source, String delimiter, String escape);
or similar, without having to do the work manually?
Without the escaping part, there are:
StringUtils.split(..) and StringUtils.join(..) from commons-lang
Joiner and Splitter from guava.
Splitting: String.split takes regex pattern as argument (delimeter) and returns String[] as result.
Split and Join escaping separator:
#NonNull
public static String joinEscaping(char separator, String... aa) {
String escape = separator != '\\' ? "\\" : "#";
StringBuilder result = new StringBuilder();
for (int i = 0; i < aa.length; i++) {
String a = aa[i];
a = (a == null) ? "" : a;
a = a.replace(escape, escape + escape);
a = a.replace(separator + "", escape + separator);
result.append(a);
if (i + 1 < aa.length) {
result.append(separator);
}
}
return result.toString();
}
public static List<String> splitUnescaping(char separator, #NonNull String str) {
char escape = separator != '\\' ? '\\' : '#';
List<String> result = new ArrayList<>();
int yourAreHere = 0;
boolean newPart = true;
while (true) {
int sep = str.indexOf(separator, yourAreHere);
int exc = str.indexOf(escape, yourAreHere);
if (sep == -1 && exc == -1) { // last part
add(result, str.substring(yourAreHere), newPart);
break;
}
if (sep == -1 && exc + 1 == str.length()) { // ghost escape
add(result, str.substring(yourAreHere, exc), newPart);
break;
}
if (exc == -1 || (sep != -1 && sep < exc)) {
add(result, str.substring(yourAreHere, sep), newPart);
yourAreHere = sep + 1;
newPart = true;
} else {
char next = str.charAt(exc + 1);
add(result, str.substring(yourAreHere, exc) + next, newPart);
yourAreHere = exc + 2;
newPart = false;
}
}
return result;
}
private static void add(List<String> result, String part, boolean newPart) {
if (newPart) {
result.add(part);
} else {
int last = result.size() - 1;
result.set(last, result.get(last) + part);
}
}
Related
There are 3 rules in the string:
It contains either word or group (enclosed by parentheses), and group can be nested;
If there is a space between word or group, those words or groups should append with "+".
For example:
"a b" needs to be "+a +b"
"a (b c)" needs to be "+a +(+b +c)"
If there is a | between word or group, those words or groups should be surround with parentheses.
For example:
"a|b" needs to be "(a b)"
"a|b|c" needs to be "(a b c)"
Consider all the rules, here is another example:
"aa|bb|(cc|(ff gg)) hh" needs to be "+(aa bb (cc (+ff +gg))) +hh"
I have tried to use regex, stack and recursive descent parser logic, but still cannot fully solve the problem.
Could anyone please share the logic or pseudo code on this problem?
New edited:
One more important rule: vertical bar has higher precedence.
For example:
aa|bb hh cc|dd (a|b) needs to be +(aa bb) +hh +(cc dd) +((a b))
(aa dd)|bb|cc (ee ff)|(gg hh) needs to be +((+aa +dd) bb cc) +((+ee +ff) (+gg +hh))
New edited:
To solve the precedence problem, I find a way to add the parentheses before calling Sunil Dabburi's methods.
For example:
aa|bb hh cc|dd (a|b) will be (aa|bb) hh (cc|dd) (a|b)
(aa dd)|bb|cc (ee ff)|(gg hh) will be ((aa dd)|bb|cc) ((ee ff)|(gg hh))
Since the performance is not a big concern to my application, this way at least make it work for me. I guess the JavaCC tool may solve this problem beautifully. Hope someone else can continue to discuss and contribute this problem.
Here is my attempt. Based on your examples and a few that I came up with I believe it is correct under the rules. I solved this by breaking the problem up into 2 parts.
Solving the case where I assume the string only contains words or is a group with only words.
Solving words and groups by substituting child groups out, use the 1) part and recursively repeating 2) with the child groups.
private String transformString(String input) {
Stack<Pair<Integer, String>> childParams = new Stack<>();
String parsedInput = input;
int nextInt = Integer.MAX_VALUE;
Pattern pattern = Pattern.compile("\\((\\w|\\|| )+\\)");
Matcher matcher = pattern.matcher(parsedInput);
while (matcher.find()) {
nextInt--;
parsedInput = matcher.replaceFirst(String.valueOf(nextInt));
String childParam = matcher.group();
childParams.add(Pair.of(nextInt, childParam));
matcher = pattern.matcher(parsedInput);
}
parsedInput = transformBasic(parsedInput);
while (!childParams.empty()) {
Pair<Integer, String> childGroup = childParams.pop();
parsedInput = parsedInput.replace(childGroup.fst.toString(), transformBasic(childGroup.snd));
}
return parsedInput;
}
// Transform basic only handles strings that contain words. This allows us to simplify the problem
// and not have to worry about child groups or nested groups.
private String transformBasic(String input) {
String transformedBasic = input;
if (input.startsWith("(")) {
transformedBasic = input.substring(1, input.length() - 1);
}
// Append + in front of each word if there are multiple words.
if (transformedBasic.contains(" ")) {
transformedBasic = transformedBasic.replaceAll("( )|^", "$1+");
}
// Surround all words containing | with parenthesis.
transformedBasic = transformedBasic.replaceAll("([\\w]+\\|[\\w|]*[\\w]+)", "($1)");
// Replace pipes with spaces.
transformedBasic = transformedBasic.replace("|", " ");
if (input.startsWith("(") && !transformedBasic.startsWith("(")) {
transformedBasic = "(" + transformedBasic + ")";
}
return transformedBasic;
}
Verified with the following test cases:
#ParameterizedTest
#CsvSource({
"a b,+a +b",
"a (b c),+a +(+b +c)",
"a|b,(a b)",
"a|b|c,(a b c)",
"aa|bb|(cc|(ff gg)) hh,+(aa bb (cc (+ff +gg))) +hh",
"(aa(bb(cc|ee)|ff) gg),(+aa(bb(cc ee) ff) +gg)",
"(a b),(+a +b)",
"(a(c|d) b),(+a(c d) +b)",
"bb(cc|ee),bb(cc ee)",
"((a|b) (a b)|b (c|d)|e),(+(a b) +((+a +b) b) +((c d) e))"
})
void testTransformString(String input, String output) {
Assertions.assertEquals(output, transformString(input));
}
#ParameterizedTest
#CsvSource({
"a b,+a +b",
"a b c,+a +b +c",
"a|b,(a b)",
"(a b),(+a +b)",
"(a|b),(a b)",
"a|b|c,(a b c)",
"(aa|bb cc|dd),(+(aa bb) +(cc dd))",
"(aa|bb|ee cc|dd),(+(aa bb ee) +(cc dd))",
"aa|bb|cc|ff gg hh,+(aa bb cc ff) +gg +hh"
})
void testTransformBasic(String input, String output) {
Assertions.assertEquals(output, transformBasic(input));
}
I tried to solve the problem. Not sure if it works in all cases. Verified with the inputs given in the question and it worked fine.
We need to format the pipes first. That will help add necessary parentheses and spacing.
The spaces generated as part of pipe processing can interfere with actual spaces that are available in our expression. So used $ symbol to mask them.
To process spaces, its tricky as parantheses need to be processed individually. So the approach I am following is to find a set of parantheses starting from outside and going inside.
So typically we have <left_part><parantheses_code><right_part>. Now left_part can be empty, similary right_part can be empty. we need to handle such cases.
Also, if the right_part starts with a space, we need to add '+' to left_part as per space requirement.
NOTE: I am not sure what's expected of (a|b). If the result should be ((a b)) or (a b). I am going with ((a b)) purely by the definition of it.
Now here is the working code:
public class Test {
public static void main(String[] args) {
String input = "aa|bb hh cc|dd (a|b)";
String result = formatSpaces(formatPipes(input)).replaceAll("\\$", " ");
System.out.println(result);
}
private static String formatPipes(String input) {
while (true) {
char[] chars = input.toCharArray();
int pIndex = input.indexOf("|");
if (pIndex == -1) {
return input;
}
input = input.substring(0, pIndex) + '$' + input.substring(pIndex + 1);
int first = pIndex - 1;
int closeParenthesesCount = 0;
while (first >= 0) {
if (chars[first] == ')') {
closeParenthesesCount++;
}
if (chars[first] == '(') {
if (closeParenthesesCount > 0) {
closeParenthesesCount--;
}
}
if (chars[first] == ' ') {
if (closeParenthesesCount == 0) {
break;
}
}
first--;
}
String result;
if (first > 0) {
result = input.substring(0, first + 1) + "(";
} else {
result = "(";
}
int last = pIndex + 1;
int openParenthesesCount = 0;
while (last <= input.length() - 1) {
if (chars[last] == '(') {
openParenthesesCount++;
}
if (chars[last] == ')') {
if (openParenthesesCount > 0) {
openParenthesesCount--;
}
}
if (chars[last] == ' ') {
if (openParenthesesCount == 0) {
break;
}
}
last++;
}
if (last >= input.length() - 1) {
result = result + input.substring(first + 1) + ")";
} else {
result = result + input.substring(first + 1, last) + ")" + input.substring(last);
}
input = result;
}
}
private static String formatSpaces(String input) {
if (input.isEmpty()) {
return "";
}
int startIndex = input.indexOf("(");
if (startIndex == -1) {
if (input.contains(" ")) {
String result = input.replaceAll(" ", " +");
if (!result.trim().startsWith("+")) {
result = '+' + result;
}
return result;
} else {
return input;
}
}
int endIndex = startIndex + matchingCloseParenthesesIndex(input.substring(startIndex));
if (endIndex == -1) {
System.out.println("Invalid input!!!");
return "";
}
String first = "";
String last = "";
if (startIndex > 0) {
first = input.substring(0, startIndex);
}
if (endIndex < input.length() - 1) {
last = input.substring(endIndex + 1);
}
String result = formatSpaces(first);
String parenthesesStr = input.substring(startIndex + 1, endIndex);
if (last.startsWith(" ") && first.isEmpty()) {
result = result + "+";
}
result = result + "("
+ formatSpaces(parenthesesStr)
+ ")"
+ formatSpaces(last);
return result;
}
private static int matchingCloseParenthesesIndex(String input) {
int counter = 1;
char[] chars = input.toCharArray();
for (int i = 1; i < chars.length; i++) {
char ch = chars[i];
if (ch == '(') {
counter++;
} else if (ch == ')') {
counter--;
}
if (counter == 0) {
return i;
}
}
return -1;
}
}
I need to fetch a sub string that lies between two same or different delimiters. The delimiters will be occurring multiple times in the string, so i need to extract the sub-string that lies between mth occurrence of delimiter1 and nth occurrence of delimiter2.
For eg:
myString : Ron_CR7_MU^RM^_SAF_34^
What should i do here if i need to extract the sub-string that lies between 3rd occurrence of '_' and 3rd occurence of '^'?
Substring = SAF_34
Or i could look for a substring that lies between 2nd '^' and 4th '_', i.e :
Substring = _SAF
An SQL equivalent would be :
substr(myString, instr(myString, '',1,3)+1,instr(myString, '^',1,3)-1-instr(myString, '',1,3))
I would use,
public static int findNth(String text, String toFind, int count) {
int pos = -1;
do {
pos = text.indexOf(toFind, pos+1);
} while(--count > 0 && pos >= 0);
return pos;
}
int from = findNth(text, "_", 3);
int to = findNth(text, "^", 3);
String found = text.substring(from+1, to);
If you can use a solution without regex you can find indexes in your string where your resulting string needs to start and where it needs to end. Then just simply perform: myString.substring(start,end) to get your result.
Biggest problem is to find start and end. To do it you can repeat this N (M) times:
int pos = indexOf(delimiterX)
myString = myString.substring(pos) //you may want to work on copy of myString
Hope you get an idea.
You could create a little method that simply hunts for such substrings between delimiters sequentially, using (as noted) String.indexOf(string); You do need to decide whether you want all substrings (whether they overlap or not .. which your question indicates), or if you don't want to see overlapping strings. Here is a trial for such code
import java.util.Vector;
public class FindDelimitedStrings {
public static void main(String[] args) {
String[] test = getDelimitedStrings("Ron_CR7_MU'RM'_SAF_34'", "_", "'");
if (test != null) {
for (int i = 0; i < test.length; i++) {
System.out.println(" " + (i + 1) + ". |" + test[i] + "|");
}
}
}
public static String[] getDelimitedStrings(String source,
String leftDelimiter, String rightDelimiter) {
String[] answer = null;
;
Vector<String> results = new Vector<String>();
if (source == null || leftDelimiter == null || rightDelimiter == null) {
return null;
}
int loc = 0;
int begin = source.indexOf(leftDelimiter, loc);
int end;
while (begin > -1) {
end = source
.indexOf(rightDelimiter, begin + leftDelimiter.length());
if (end > -1) {
results.add(source.substring(begin, end));
// loc = end + rightDelimiter.length(); if strings must be
// returned as pairs
loc = begin + 1;
if (loc < source.length()) {
begin = source.indexOf(leftDelimiter, loc);
} else {
begin = -1;
}
} else {
begin = -1;
}
}
if (results.size() > 0) {
answer = new String[results.size()];
results.toArray(answer);
}
return answer;
}
}
I'd like to split a string at comma ",". The string contains escaped commas "\," and escaped backslashs "\\". Commas at the beginning and end as well as several commas in a row should lead to empty strings.
So ",,\,\\,," should become "", "", "\,\\", "", ""
Note that my example strings show backslash as single "\". Java strings would have them doubled.
I tried with several packages but had no success. My last idea would be to write my own parser.
In this case a custom function sounds better for me. Try this:
public String[] splitEscapedString(String s) {
//Character that won't appear in the string.
//If you are reading lines, '\n' should work fine since it will never appear.
String c = "\n";
StringBuilder sb = new StringBuilder();
for(int i = 0;i<s.length();++i){
if(s.charAt(i)=='\\') {
//If the String is well formatted(all '\' are followed by a character),
//this line should not have problem.
sb.append(s.charAt(++i));
}
else {
if(s.charAt(i) == ',') {
sb.append(c);
}
else {
sb.append(s.charAt(i));
}
}
}
return sb.toString().split(c);
}
Don't use .split() but find all matches between (unescaped) commas:
List<String> matchList = new ArrayList<String>();
Pattern regex = Pattern.compile(
"(?: # Start of group\n" +
" \\\\. # Match either an escaped character\n" +
"| # or\n" +
" [^\\\\,]++ # Match one or more characters except comma/backslash\n" +
")* # Do this any number of times",
Pattern.COMMENTS);
Matcher regexMatcher = regex.matcher(subjectString);
while (regexMatcher.find()) {
matchList.add(regexMatcher.group());
}
Result: ["", "", "\\,\\\\", "", ""]
I used a possessive quantifier (++) in order to avoid excessive backtracking due to the nested quantifiers.
While certainly a dedicated library is a good idea the following will work
public static String[] splitValues(final String input) {
final ArrayList<String> result = new ArrayList<String>();
// (?:\\\\)* matches any number of \-pairs
// (?<!\\) ensures that the \-pairs aren't preceded by a single \
final Pattern pattern = Pattern.compile("(?<!\\\\)(?:\\\\\\\\)*,");
final Matcher matcher = pattern.matcher(input);
int previous = 0;
while (matcher.find()) {
result.add(input.substring(previous, matcher.end() - 1));
previous = matcher.end();
}
result.add(input.substring(previous, input.length()));
return result.toArray(new String[result.size()]);
}
Idea is to find , prefixed by no or even-numbered \ (i.e. not escaped ,) and as the , is the last part of the pattern cut at end()-1 which is just before the ,.
Function is tested against most odds I can think of except for null-input. If you like handling List<String> better you can of course change the return; I just adopted the pattern implemented in split() to handle escapes.
Example class uitilizing this function:
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Print {
public static void main(final String[] args) {
String input = ",,\\,\\\\,,";
final String[] strings = splitValues(input);
System.out.print("\""+input+"\" => ");
printQuoted(strings);
}
public static String[] splitValues(final String input) {
final ArrayList<String> result = new ArrayList<String>();
// (?:\\\\)* matches any number of \-pairs
// (?<!\\) ensures that the \-pairs aren't preceded by a single \
final Pattern pattern = Pattern.compile("(?<!\\\\)(?:\\\\\\\\)*,");
final Matcher matcher = pattern.matcher(input);
int previous = 0;
while (matcher.find()) {
result.add(input.substring(previous, matcher.end() - 1));
previous = matcher.end();
}
result.add(input.substring(previous, input.length()));
return result.toArray(new String[result.size()]);
}
public static void printQuoted(final String[] strings) {
if (strings.length > 0) {
System.out.print("[\"");
System.out.print(strings[0]);
for(int i = 1; i < strings.length; i++) {
System.out.print("\", \"");
System.out.print(strings[i]);
}
System.out.println("\"]");
} else {
System.out.println("[]");
}
}
}
I have used below solution for generic sting splitter with quotes(' and ") and escape(\) character.
public static List<String> split(String str, final char splitChar) {
List<String> queries = new ArrayList<>();
int length = str.length();
int start = 0, current = 0;
char ch, quoteChar;
while (current < length) {
ch=str.charAt(current);
// Handle escape char by skipping next char
if(ch == '\\') {
current++;
}else if(ch == '\'' || ch=='"'){ // Handle quoted values
quoteChar = ch;
current++;
while(current < length) {
ch = str.charAt(current);
// Handle escape char by skipping next char
if (ch == '\\') {
current++;
} else if (ch == quoteChar) {
break;
}
current++;
}
}else if(ch == splitChar) { // Split sting
queries.add(str.substring(start, current + 1));
start = current + 1;
}
current++;
}
// Add last value
if (start < current) {
queries.add(str.substring(start));
}
return queries;
}
public static void main(String[] args) {
String str = "abc,x\\,yz,'de,f',\"lm,n\"";
List<String> queries = split(str, ',');
System.out.println("Size: "+queries.size());
for (String query : queries) {
System.out.println(query);
}
}
Getting result
Size: 4
abc,
x\,yz,
'de,f',
"lm,n"
For records:
X means anything
Y means year
M means month
N means numeric
A means alphabet
For example:
my input mask from database is like this:
XXXYMXXXXXA
and my input is:
39JY412345O
i want check this input is valid or invalid but i can't check it with mask, I want replace mask with regular expression like this for its input mask:
/^.{3}Y[0-9]{1}.{5}[a-zA-Z]{1}$/
I don't have regular expression, I have input mask only.I have input validation and it use regular expression for checking valid or invalid inputs. I should replace regular expression with my input mask ( 200 kind of input mask ) and I use its regular expression for validation
I need to write a method that translates from an input mask (such as "XXXYMXXXXXA") to a regex in the java.lang.regex.Pattern format (such as ".{3}Y[0-9]{1}.{5}[a-zA-Z]{1}")
This is my method code: ( but I want best practice for this solution )
private String replaceAll(String pattern, String value, String replaceValue) {
String str = value;
str = str.replaceAll(pattern, replaceValue.concat("{").concat("1").concat("}"));
return str;
}
and method calls:
String anything = "[Xx]";
String alphabet = "[Aa]";
String number = "[Nn]";
String word = getName();
word = replaceAll(anything, word, ".");
word = replaceAll(alphabet, word, "[A-Za-z]");
word = replaceAll(number, word, "[0-9]");
Assuming a general approach, there is a mapping between one char in the mask (e.g. 'X') to one part of a regular expression (e.g. '.'), and recurrent mask chars result in a numeric quantifier (like {3}).
So I've put together a helper class, and a simple test method, so maybe this is a point to start from.
Helper class:
import java.util.HashMap;
import java.util.Map;
public class PatternBuilder {
protected Map<Character, String> mappings = new HashMap<Character, String>();
protected boolean caseSensitive = false;
public PatternBuilder() {
}
public PatternBuilder(boolean caseSensitive) {
this.caseSensitive = caseSensitive;
}
public PatternBuilder addDefinition(char input, String mapping) {
if (this.caseSensitive) {
this.mappings.put(input, mapping);
} else {
this.mappings.put(Character.toLowerCase(input), mapping);
}
return this;
}
public String buildRegexPattern(String mask) {
if ((mask == null) || (mask.length() == 0)) {
return "";
}
StringBuilder patternBuffer = new StringBuilder();
char lastChar = 0;
int count = 0;
for (int i = 0; i < mask.length(); i++) {
char c = mask.charAt(i);
if (this.caseSensitive == false) {
c = Character.toLowerCase(c);
}
if (c != lastChar) {
if (count > 0) {
String mapped = mappings.get(lastChar);
if (mapped == null) {
// mapping for char not defined
return "";
}
patternBuffer.append(mapped);
patternBuffer.append("{").append(count).append("}");
}
lastChar = c;
count = 1;
} else {
count++;
}
}
if (count > 0) {
String mapped = mappings.get(lastChar);
if (mapped == null) {
mapped = ".";
}
patternBuffer.append(mapped);
patternBuffer.append("{").append(count).append("}");
}
return patternBuffer.toString();
}
}
Usage:
PatternBuilder patternBuilder = new PatternBuilder()
.addDefinition('X', ".")
.addDefinition('Y', "Y")
.addDefinition('M', "[0-9]")
.addDefinition('N', "\\d")
.addDefinition('A', "[a-zA-Z]");
String rePattern = patternBuilder.buildRegexPattern("XxxYMXXXXXA"); // case insensitive, x == X
System.out.println("Pattern: '" + rePattern + "'");
Pattern p = Pattern.compile(rePattern);
String[] tests = new String[]{
"39JY412345O", // Original, match
"39JY41234FO", // replaced 5 with F, still matching
"39JY4123457", // replaced O with 7, no match
"A9JY4123457" // replaced 3 with A, no match
};
for (String s : tests) {
Matcher m = p.matcher(s);
System.out.println("Test '" + s + "': " + m.matches());
}
My output:
Pattern: '.{3}Y{1}[0-9]{1}.{5}[a-zA-Z]{1}'
Test '39JY412345O': true
Test '39JY41234FO': true
Test '39JY4123457': false
Test 'A9JY4123457': false
I have this code:
String s = "A very long string containing " +
"many many words and characters. " +
"Newlines will be entered at spaces.";
StringBuilder sb = new StringBuilder(s);
int i = 0;
while ((i = sb.indexOf(" ", i + 20)) != -1) {
sb.replace(i, i + 1, "\n");
}
System.out.println(sb.toString());
The output of the code is:
A very long string containing
many many words and
characters. Newlines
will be entered at spaces.
The above code is wrapping the string after the next space of every 30 characters, but I need to wrap the string after the previous space of every 30 characters, like for the first line it will be:
A very long string
And the 2nd line will be
containing many
Please give some proper solution.
You can use Apache-common's WordUtils.wrap().
Use lastIndexOf instead of indexOf, e.g.
StringBuilder sb = new StringBuilder(s);
int i = 0;
while (i + 20 < sb.length() && (i = sb.lastIndexOf(" ", i + 20)) != -1) {
sb.replace(i, i + 1, "\n");
}
System.out.println(sb.toString());
This will produce the following output:
A very long string
containing many
many words and
characters.
Newlines will be
entered at spaces.
You can try the following:
public static String wrapString(String s, String deliminator, int length) {
String result = "";
int lastdelimPos = 0;
for (String token : s.split(" ", -1)) {
if (result.length() - lastdelimPos + token.length() > length) {
result = result + deliminator + token;
lastdelimPos = result.length() + 1;
}
else {
result += (result.isEmpty() ? "" : " ") + token;
}
}
return result;
}
call as wrapString("asd xyz afz","\n",5)
I know it's an old question, but . . . Based on another answer I found here, but can't remember the posters name. Kuddos to him/her for pointing me in the right direction.
public String truncate(final String content, final int lastIndex) {
String result = "";
String retResult = "";
//Check for empty so we don't throw null pointer exception
if (!TextUtils.isEmpty(content)) {
result = content.substring(0, lastIndex);
if (content.charAt(lastIndex) != ' ') {
//Try the split, but catch OutOfBounds in case string is an
//uninterrupted string with no spaces
try {
result = result.substring(0, result.lastIndexOf(" "));
} catch (StringIndexOutOfBoundsException e) {
//if no spaces, force a break
result = content.substring(0, lastIndex);
}
//See if we need to repeat the process again
if (content.length() - result.length() > lastIndex) {
retResult = truncate(content.substring(result.length(), content.length()), lastIndex);
} else {
return result.concat("\n").concat(content.substring(result.length(), content.length()));
}
}
//Return the result concatenating a newline character on the end
return result.concat("\n").concat(retResult);;
//May need to use this depending on your app
//return result.concat("\r\n").concat(retResult);;
} else {
return content;
}
}
public static void main(String args[]) {
String s1="This is my world. This has to be broken.";
StringBuffer buffer=new StringBuffer();
int length=s1.length();
int thrshld=5; //this valueis threshold , which you can use
int a=length/thrshld;
if (a<=1) {
System.out.println(s1);
}else{
String split[]=s1.split(" ");
for (int j = 0; j < split.length; j++) {
buffer.append(split[j]+" ");
if (buffer.length()>=thrshld) {
int lastindex=buffer.lastIndexOf(" ");
if (lastindex<buffer.length()) {
buffer.subSequence(lastindex, buffer.length()-1);
System.out.println(buffer.toString());
buffer=null;
buffer=new StringBuffer();
}
}
}
}
}
this can be one way to achieve
"\n" makes a wordwrap.
String s = "A very long string containing \n" +
"many many words and characters. \n" +
"Newlines will be entered at spaces.";
this will solve your problem