1

I want to build a pattern to insert comma into integer to make it looks nice , like 1234556, after manipulating , it will be like 1,234,556 , so I use the following code:

public static void insertCommaFormly(int n)
    {
        String input = String.valueOf(n);
        String regex = "(?<=\\d)(?=(?:\\d{3},?)+$)";
        /*or we can use negative look-around*/
        regex = "(?<=\\d)(?=\\d{3}++\\b)";
        String replacement = ",";
        StringBuffer buffer = new StringBuffer();
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(input);

        logger.info("Target string is :" + input );
        logger.info("Use regex :" + regex);

        while(matcher.find())
        {
            matcher.appendReplacement(buffer, replacement);
            logger.info(String.format("Part : '%s'", buffer));
        }
        matcher.appendTail(buffer);

        logger.info("After replace , the string is like : " + buffer.toString());
    } 

However , it gives me an error(I don't know the reason!):

Dangling meta character '+' near index 16
(?<=\d)(?=\d{2}++\b)
                ^

but if I use (?<=\\d)(?=\\d{3}+\\b) , the compiler will not give me complaint , however , it gives me the wrong result 1234,556(I don't know why results in this ?) ,if I use (?<=\\d)(?=(?:\\d{3})+\\b), then it would be the right result.

  So here are my two questions , please help me with these , thanks in advance!
ohyeahchenzai
  • 314
  • 3
  • 13

3 Answers3

1

Why not use the ready-made DecimalFormat class which will put the commas in for you? See this question

The 'dangling meta-character' error is because '+' has special meaning within a regular expression (one or more occurrences of the previous character), if you remove the second '+' it should be valid.

Community
  • 1
  • 1
codebox
  • 19,927
  • 9
  • 63
  • 81
1

In \d{3}++, the {3} is a quantifier which means exactly three, and the first + makes the quantifier possessive, which is syntactically valid, however pointless. But the second + makes no sense at all; it can't serve as either a quantifier or a possessive modifier, which is why you're getting that exception.

What you're trying to do is match a position that is followed by some digits, where the number of digits is a multiple of three--or, in terms that can be expressed as a regex, one or more groups of three digits:

(?=(?:\d{3})+)

You can add a second + to make it possessive if you like - (?=(?:\d{3})++) - but it won't change the results and it won't have a noticeable effect on performance. By the way, you don't really have to use appendReplacement() and appendTail() for this job:

return String.valueOf(n).replaceAll("(?<=\\d)(?=(?:\\d{3})+$)", ",");

...works just fine.

Alan Moore
  • 73,866
  • 12
  • 100
  • 156
0

One could use the DecimalFormat class:

    int i = 1234556;
    DecimalFormat df = new DecimalFormat("###,###");
    String result = df.format(i);
    System.out.println(result);
Michael Besteck
  • 2,415
  • 18
  • 10