7

Possible Duplicate:
Parsing numbers safely and locale-sensitively

How can I validate strings containing decimal numbers in a locale-sensitive way? NumberFormat.parse allows too much, and Double.parseDouble works only for English locale. Here is what I tried:

public static void main(String[] args) throws ParseException {
    Locale.setDefault(Locale.GERMAN);

    NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.getDefault());
    Number parsed = numberFormat.parse("4,5.6dfhf");
    System.out.println("parsed = " + parsed); // prints 4.5 instead of throwing ParseException

    double v = Double.parseDouble("3,3"); // throws NumberFormatException, although correct
}
Community
  • 1
  • 1
WannaKnow
  • 1,155
  • 2
  • 11
  • 18

2 Answers2

2

In regards of the

Number parsed = numberFormat.parse("4,5.6dfhf");

problem, you could possibly use NumberFormat.parse(String source, ParsePosition pos) and check if the position where it stopped parsing was indeed the last position of the string.

Also, on the 4.5.6 problem, you can try to set grouping off by setGroupingUsed(boolean newValue) as I think it's an issue produced by the '.' character being the grouping character on the locale.

It should be something like

NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.getDefault());
numberFormat.setGroupingUsed(false);
ParsePosition pos;
String nString = "4,5.6dfhf";

Number parsed = numberFormat.parse(nString, pos);
if (pos.getIndex() == nString.length()) // pos is set AFTER the last parsed position
   System.out.println("parsed = " + parsed);
else
   // Wrong
Manuel Miranda
  • 823
  • 5
  • 13
1

From your comment above, you can use:

String input = "3,3"; // or whatever you want
boolean isValid = input.matches("^\\d+([.,]\\d+)?$");
double value = Double.parseDouble(input.replaceAll(",", "."));

If the separator can be something else besides the comma, just add it in the square brackets:

double value = Double.parseDouble(input.replaceAll("[,]", "."));
jlordo
  • 37,490
  • 6
  • 58
  • 83
  • The problem is that it is not guaranteed that the locale is German. It could be anything. You think that this would work for any locale? – WannaKnow Jan 07 '13 at 11:37
  • As long as the separator is a dot or a comma, it will work. I don't know of a locale, where the separator is something else. – jlordo Jan 07 '13 at 11:39
  • How about spaces? `1 000 000` is probably valid in some locales. Trying to redevelop a locale-dependent parser sounds like a dangerous game... – assylias Jan 07 '13 at 11:42
  • This depends on how strict you want to be. If `1 000 000` is valid, is this `1 00 0000` or more than one space also? – jlordo Jan 07 '13 at 11:44
  • @jlordo Exactly - it brings many border cases and it is very difficult to get it right. – assylias Jan 07 '13 at 11:47
  • IMHO a number in input can only be a sequence of digits optionally followed by a separator and another sequence of digits. Presenting (pretty printing) numbers is a completely different thing. – jlordo Jan 07 '13 at 11:48