5

Pretty basic problem, but difficult to get into an acceptable form:

I want to transform a string by inserting a padding every 3 whitespaces like

"123456789" -> "123 456 789"

"abcdefgh" -> "abc def gh"

My code currently is

public String toSpaceSeparatedString(String s) {
  if (s == null || s.length() < 3) {
    return s;
  }

  StringBuilder builder = new StringBuilder();
  int i; 
  for (i = 0; i < s.length()-3; i += 3) {
    builder.append(s.substring(i, i+3));
    builder.append(" ");
  }

  builder.append(s.substring(i, s.length()));

  return builder.toString();
}

Can anyone provide a more elegant solution?

Johannes Charra
  • 29,455
  • 6
  • 42
  • 51

4 Answers4

10

You can do this using a regular expression:

"abcdefgh".replaceAll(".{3}", "$0 ")
wjans
  • 10,009
  • 5
  • 32
  • 43
  • Thanks, I found a similar solution, but regex for such a simple task is always the _last_ resort. ;) – Johannes Charra Jun 22 '11 at 10:58
  • 1
    Really? I think regex is always the FIRST resort! – Bohemian Jun 22 '11 at 11:04
  • It can be done via an even easier regex. Updated the answer. – wjans Jun 22 '11 at 11:05
  • @jellybean: it is a one-liner. if you add a good comment about what it is doing or put it into an utility method with a meaningful name, I think it's perfectly fine to use regex here. – Denis Tulskiy Jun 22 '11 at 11:05
  • After the update it's much more readable/acceptable, thank you. – Johannes Charra Jun 22 '11 at 11:07
  • @Bohemian: Not for me, I guess. ;) @tulskiy: I'm pretty suspicious about comments that make claims about how code behaves ... the code should be at least in some degree be comprehensible. But that topic has probably argued about a lot already ... – Johannes Charra Jun 22 '11 at 11:16
3

You can use printf or String.format like so:

 builder.append(String.format("%4s", threeDigitString));

More information on formatted output/strings in the API.

dcn
  • 4,389
  • 2
  • 30
  • 39
  • This is meant as a replacement for the code inside the `for` loop, as well as the append afterwards, right? Not bad, but I'd like to get rid of the ugly form of the loop. – Johannes Charra Jun 22 '11 at 11:05
1

The replaceAll looks to be the best, but if you consider a number like 12345 it would be converted to 123 45. But in numbers I believe it should be 12 345

MaVRoSCy
  • 17,747
  • 15
  • 82
  • 125
1

This doesn't put a space if there's already one there:

"abcdef gh".replaceAll("\\s*(..[^ ])\\s*", "$1 "); // --> "abc def gh"
Bohemian
  • 412,405
  • 93
  • 575
  • 722