Search code examples
javavalidationnumber-formatting

How to parse numbers more strict than what NumberFormat does in Java?


I'm validating user input from a form.

I parse the input with NumberFormat, but it is evil and allow almost anything. Is there any way to parse number more strict?

E.g. I would like to not allow these three inputs, for an integer, but Numberformat allow all of them:

NumberFormat nf = NumberFormat.getNumberInstance();
nf.setParseIntegerOnly(true);

Number numberA = nf.parse("99.731");    // 99 (not what the user expect)
Number numberB = nf.parse("99s.231");   // 99 (invalid)
Number numberC = nf.parse("9g9");       // 9  (invalid)

System.out.println(numberA.toString());
System.out.println(numberB.toString());
System.out.println(numberC.toString());

Solution

  • Maybe this helps:

    The NumberFormat classes that come with the JDK don't allow for strict number parsing. This has been filed as an enhancement here: https://bugs.java.com/bugdatabase/view_bug?bug_id=6431200 where a workaround is listed.

    "Use a ParsePosition to get the index after parsing. If ParsePostion.getIndex() != string.length(), then parse() didn't consume the entire string."

    Actually, you can also add a check to make sure the error index is -1. Values other than -1 mean that there was an error. Trimming the value before parsing is also a good idea. The end product might look something like this:

    String value = "number_to_be_parsed".trim();
    NumberFormat formatter = NumberFormat.getNumberInstance();
    ParsePosition pos = new ParsePosition(0);
    Number parsed = formatter.parse(value, pos);
    if (pos.getIndex() != value.length() || pos.getErrorIndex() != -1) {
        throw new RuntimeException("my error description");
    }
    

    (Thanks to Strict number parsing at mynetgear.net)