That is not possible with DecimalFormatter
and NumberFormatter
. But you can use a trick with String
and regular expression:
Long.toString(number)
.replaceAll("(\\d{2})(\\d{5})(\\d{5})(\\d)", "$1 $2 $3 $4");
If your format is dynamic, you could do something like this:
@Test
void simon() {
final var input = 1234567890123L;
assertEquals("12 34567 89012 3", formatMyNumber(input, "{2} {5} {5} {1}"));
assertEquals("12-34567-89012-3", formatMyNumber(input, "{2}-{5}-{5}-{1}"));
assertEquals("12_34567_89012_3", formatMyNumber(input, "{2}_{5}_{5}_{1}"));
assertEquals("1 23456 7", formatMyNumber(1234567, "{1} {5} {1}"));
assertEquals("1 2345 6", formatMyNumber(123456, "{1} {4} {1}"));
assertEquals("123.45.6", formatMyNumber(123456, "{3}.{2}.{1}"));
}
private String formatMyNumber(final long number, final String format) {
return Long.toString(number).replaceAll(createRegEx(format), createReplacement(format));
}
private String createRegEx(final String format) {
final var separator = getSeparator(format);
return format.replaceAll("\\{", "(\\\\d{")
.replaceAll("}" + Pattern.quote(separator), "}\\)")
.replaceAll("}$", "}\\)"); // could be integrated in above regex
}
private String getSeparator(final String format) {
final var begin = format.indexOf("}");
final var end = format.indexOf("{", begin);
return format.substring(begin + 1, end);
}
private String createReplacement(final String format) {
final var separator = getSeparator(format);
var replacement = format.replaceAll("^\\{\\d", "\\$X")
.replaceAll("}" + Pattern.quote(separator) + "\\{\\d", separator + "\\$X")
.replaceAll("}$", "");
var counter = 1;
while (replacement.contains("X")) {
replacement = replacement.replaceFirst("X", Integer.toString(counter++));
}
return replacement;
}
It's not my best piece of work but works with dynamic format strings.