Find/replace number with commas in Java

Posted on

Problem

I have a requirement to put a comma between each digit of a number in a Java string.

Example input:

the number is 12345 and the number is 45678

The output should be:

the number is 1,2,3,4,5 and the number is 4,5,6,7,8

I wrote the following and I am not sure if it is optimized. If someone reviews it and help me fine tune it, it will be helpful.

public static void main(String args[]) {
      String str = "the number is 12345 and the number is 45678";
      System.out.println("Original Text:n" + str);
      System.out.println("Updated Text:n" + formatNumber(str, ','));
   }

   public static String formatNumber(String text, char separator) {
       Pattern p = Pattern.compile("\d+");
       Matcher m = p.matcher(text);
       StringBuffer sb = new StringBuffer();
       while(m.find()) {
           String num = m.group();
           num = num.replaceAll(".(?!$)", "$0"+separator);
           m.appendReplacement(sb,num);
       }
       return m.appendTail(sb).toString();
   }

Output:

Original Text:
    the number is 12345 and the number is 45678
    Updated Text:
    the number is 1,2,3,4,5 and the number is 4,5,6,7,8
    Process finished with exit code 0

Though it gave me the output I wanted, I have a feeling that it is not highly optimized when the string size grows larger and larger.

Solution

Two of the really nice things about regular expressions are:

  1. they can be compiled, which makes them fast, and reusable
  2. they can replace what’s between characters, not just the characters themselves.

In your case, you can reduce it to a “simple” lookaround regular expression. What you are looking for, is the gap between two digits…

in a regular expression, the gap can have no width. So, look for a place that follows a digit, and is also followed by a digit. Then, replace that place with a separator.

Then, compile and save that expression away, and reuse it:

private static final Pattern BETWEEN_DIGITS = Pattern.compile("(?<=\d)(?=\d)");

public static String formatNumber(String text, char separator) {
    return BETWEEN_DIGITS.matcher(text).replaceAll("" + separator);
}

That pattern is complicated…. but read up on look-behinds, and look-aheads: http://www.regular-expressions.info/lookaround.html

Leave a Reply

Your email address will not be published. Required fields are marked *