1

I have a string that I'm trying to parse into a BigDecimal. I'm using the following regex to strip all non currency symbols with the exception of -,.()$. Once it has been stripped, I'm then trying to create a BigDecimal with the remaining value. The problem begins when a negative value comes across in brackets. Does anybody have any suggestions on how to repair this instance?

(1000.00) fails

I'm assuming I must somehow convert the brackets to a negative sign.

code sample.

public BigDecimal parseClient(Field field, String clientValue, String message) throws ValidationException {
    if (clientValue == null) {
        return null;
    }

    try {
        clientValue = clientValue.replaceAll( "[^\\d\\-\\.\\(\\)]", "" );
        return new BigDecimal(clientValue.toString());
    } catch (NumberFormatException ex) {
        throw new ValidationException(message);
    }
}
Code Junkie
  • 7,602
  • 26
  • 79
  • 141
  • You don't describe the format of your input string. Is it really so strange, that you cannot use a DecimalFormat instance to parse the string? If not, why are you trying to reinvent the wheel by manipulating the string yourself? – jarnbjo Feb 13 '13 at 17:55
  • Does this help: http://stackoverflow.com/questions/2056400/format-negative-amount-of-usd-with-a-minus-sign-not-brackets-java – GJ13 Feb 13 '13 at 18:07
  • The values are entered in by a user. Those values very as such, $5,000.00, 5,000.00, 5000.00, 5000, -5000.00, (5000.00), ($5000.00), (-5000.00), ($-5000.00). In the end they need to either be 5000.00, (-5000.00), -5000.00 so that they can be passed into a bigdecimal. – Code Junkie Feb 13 '13 at 19:09
  • @GJ13, I've seen that post, but I don't understand how the format will strip the unwanted characters. – Code Junkie Feb 13 '13 at 19:10

3 Answers3

2

You will need to detect the ( and ) characters yourself, then strip them out, create a BigDecimal from the rest of the string, and negate it.

if (clientValue.startsWith('(') && clientValue.endsWith(')'))
{
   return new BigDecimal(clientValue.substring(1, clientValue.length() - 1)).negate();
}
else
{
   return new BigDecimal(clientValue);
}
rgettman
  • 176,041
  • 30
  • 275
  • 357
  • This would almost work, however when you have (-1000.00) which is a valid value negates to positive 1000.00 – Code Junkie Feb 13 '13 at 19:52
  • Then you'll need to detect a possible '-' character at the start of the substring, and if it's there, don't negate, so that your result stays negative. – rgettman Feb 13 '13 at 19:57
  • That's what I did although mathematically wouldn't that be a negative number? – Code Junkie Feb 13 '13 at 20:11
  • There's 2 ways of indicating a negative number: The normal mathematics minus sign, e.g -1000.00, and the accounting way, e.g. (1000.00). Your first comment indicates that if BOTH are given, e.g. (-1000.00), that the number should be remain negative. That's what drove my first comment above. – rgettman Feb 13 '13 at 20:16
1

What makes you think parentheses are correctly interpreted by BigDecimal? (1000.00) is incorrect input according to the documentation. You must use - symbol (-1000.00). Supported format is strictly defined in JavaDoc. In general it's optional symbol (+ or -) followed by digits, dot (.) and exponent.

For example this is valid input: -1.1e-10.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • So your suggesting appending the negative sign after the first brace? – Code Junkie Feb 13 '13 at 17:47
  • Okay, I must of simply overlooked this since the CurrencyFormatter was sending the values to the frontend without the minus sign causing it to fail when being submitted to the backend. – Code Junkie Feb 13 '13 at 17:49
1

DecimalFormat is a more appropriate tool for the job:

DecimalFormat myFormatter = new DecimalFormat("¤#,##0.00;(¤#,##0.00)");
myFormatter.setParseBigDecimal(true);
BigDecimal result = (BigDecimal) myFormatter.parse("(1000.00)");
System.out.println(result); // -1000.00 for Locale.US
System.out.println(myFormatter.parse("($123,456,789.12)")); // -123456789.12

As you can see, not only will it deal with negative patterns, but also with currency signs, decimal and grouping separators, localization issues, etc.

Take a look at The Java Tutorials: Customizing Formats for further info.

Anthony Accioly
  • 21,918
  • 9
  • 70
  • 118