tags:

views:

3338

answers:

5

I have a java string, which has a variable length.

I need to put the piece "<br>" into the string, say each 10 characters.

For example this is my string:

`this is my string which I need to modify...I love stackoverlow:)`

How can I obtain this string?:

`this is my<br> string wh<br>ich I nee<br>d to modif<br>y...I love<br> stackover<br>flow:)`

Thanks

+11  A: 

Try:

String s = // long string
s.replaceAll("(.{10})", "$1<br>");

EDIT: The above works... most of the time. I've been playing around with it and came across a problem: since it constructs a default Pattern internally it halts on newlines. to get around this you have to write it differently.

public static String insert(String text, String insert, int period) {
    Pattern p = Pattern.compile("(.{" + period + "})", Pattern.DOTALL);
    Matcher m = p.matcher(text);
    return m.replaceAll("$1" + insert);
}

and the astute reader will pick up on another problem: you have to escape regex special characters (like "$1") in the replacement text or you'll get unpredictable results.

I also got curious and benchmarked this version against Jon's above. This one is slower by an order of magnitude (1000 replacements on a 60k file took 4.5 seconds with this, 400ms with his). Of the 4.5 seconds, only about 0.7 seconds was actually constructing the Pattern. Most of it was on the matching/replacement so it doesn't even ledn itself to that kind of optimization.

I normally prefer the less wordy solutions to things. After all, more code = more potential bugs. But in this case I must concede that Jon's version--which is really the naive implementation (I mean that in a good way)--is significantly better.

cletus
I'm getting:Invalid escape sequence (valid ones are \b \t \n \f \r \" \' \\ )for "(.{1,10}\s+"
Boris Pavlović
Fixed it. It should've been \\s but I'd mistakenly assumed you wanted to break on word boundaries. You don't so the above should work and is much easier.
cletus
This one works for me.
Outlaw Programmer
+4  A: 

Something like:

public static String insertPeriodically(
    String text, String insert, int period)
{
    StringBuilder builder = new StringBuilder(
         text.length() + insert.length() * (text.length()/period)+1);

    int index = 0;
    String prefix = "";
    while (index < text.length())
    {
        // Don't put the insert in the very first iteration.
        // This is easier than appending it *after* each substring
        builder.append(prefix);
        prefix = insert;
        builder.append(text.substring(index, 
            Math.min(index + period, text.length())));
        index += period;
    }
    return builder.toString();
}
Jon Skeet
fantastic! and what about if I do not want to put <br> within words? for example avoiding things like: stackover<br>flow and putting directly <br> at the end of the word?
Giancarlo
Then that's a significantly harder problem. A regular expression *may* be the best way there, but you'd need to state the requirements *very* precisely first.
Jon Skeet
A: 
StringBuffer buf = new StringBuffer();

for (int i=0;i<myString.length();i+=10) {
    buf.append(myString.substring(i,i+10);
    buf.append("\n");
}

You can get more efficient than that, but I'll leave that as an exercise for the reader.

DJClayworth
Missing a trailing paren on the first append, also goes out of the string bounds
Stephen Pape
You should probably use StringBuilder not StringBuffer.
cletus
That's the sort of exercise I left for the reader.
DJClayworth
For big Strings it might be a good idea to set the initial size of the StringBuffer/StringBuilder to (myString.length()*1.1) this way resizing the internal buffer will be avoided.
Joachim Sauer
A: 

How about 1 method to split the string every N characters:

public static String[] split(String source, int n)
{
    List<String> results = new ArrayList<String>();

    int start = 0;
    int end = 10;

    while(end < source.length)
    {
        results.add(source.substring(start, end);
        start = end;
        end += 10;
    }

    return results.toArray(new String[results.size()]);
}

Then another method to insert something after each piece:

public static String insertAfterN(String source, int n, String toInsert)
{
    StringBuilder result = new StringBuilder();

    for(String piece : split(source, n))
    {
        result.append(piece);
        if(piece.length == n)
            result.append(toInsert);
    }

    return result.toString();
}
Outlaw Programmer
+1  A: 

To avoid chopping off the words...

Try:

    int wrapLength = 10;
 String wrapString = new String();

    String remainString = "The quick brown fox jumps over the lazy dog The quick brown fox jumps over the lazy dog";

 while(remainString.length()>wrapLength){
  int lastIndex = remainString.lastIndexOf(" ", wrapLength);
  wrapString = wrapString.concat(remainString.substring(0, lastIndex));
  wrapString = wrapString.concat("\n");

  remainString = remainString.substring(lastIndex+1, remainString.length());
 }

 System.out.println(wrapString);