Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behaviour of NumberFormat Java

I have the following code to parse a String variable called str.

NumberFormat formatter = NumberFormat.getInstance();
Number number = formatter.parse(str);

I want to catch the Exception thrown when str is not a number just to validate it. The problem I have is that it does't always throws the ParseException expected. When the String str starts with a number but then are characters it seems to get a the first characters of the String and parse them as a number.

For example:

  • if str="a10" then is thrown a ParseException
  • if str="10a" then no exception thrown and number=10

I cannot use Double.parseDouble(str) because str can have commas and points like 1,000.98 and this format is not understood by this method.

Why is this happening? Can I validate it in any other way? Thanks

like image 990
Javi Avatar asked Feb 15 '10 12:02

Javi


2 Answers

The behaviour is not strange, it's as designed

Parses text from the beginning of the given string to produce a number. The method may not use the entire text of the given string.

You may use the position-aware parsing method like this:

public static double parse(String str) throws ParseException {
  NumberFormat formatter = NumberFormat.getInstance();
  ParsePosition position = new ParsePosition(0);
  Number number = formatter.parse(str, position);
  if (position.getIndex() != str.length()) {
    throw new ParseException("failed to parse entire string: " + str, position.getIndex());
  }
  return number.doubleValue();
} 
like image 126
sfussenegger Avatar answered Nov 15 '22 09:11

sfussenegger


If you look at the API, it clearly says:

Parses text from the beginning of the given string to produce a number. The method may not use the entire text of the given string.

If you want to see how far the parser parsed, you can use the other position-aware method. This way you can check if you have any trailing chars. You could also check the whole string for alphanumeric chars using for instance common langs isAlpha.

like image 35
Alexander Torstling Avatar answered Nov 15 '22 10:11

Alexander Torstling