Jonas
Jonas

Reputation: 128827

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());

Upvotes: 12

Views: 5224

Answers (7)

napu
napu

Reputation: 456

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)

Upvotes: 12

marcolopes
marcolopes

Reputation: 9287

I gave up on writing my own validation class, and went with NEBULA WIDGETS FormattedText

It was written over the SWT widget API, but you can easily adapt the NumberFormatter class

Upvotes: 0

Matt
Matt

Reputation: 1

I wouldn't use java's number format routine, especially with the locale settings if you worry about validation.

    Locale numberLocale = new Locale(“es”,”ES");
    NumberFormat nf = NumberFormat.getInstance(numberLocale);
    ParsePosition pos = new ParsePosition(0);
    Number test = nf.parse("0.2", pos);

You would expect there to be an issue here, but no.. test is equal to 2 and pos has an index of 3 and error index of -1.

Upvotes: 0

Ian McLaird
Ian McLaird

Reputation: 5585

Integer.parseInt(String) will throw a NumberFormatException on all of your examples. I'm not sure if that's what you're looking for, but it's definitely "more strict."

Upvotes: 2

Thomas Johan Eggum
Thomas Johan Eggum

Reputation: 915

Take a look at DecimalFormat that is a subclass of NumberFormat http://docs.oracle.com/javase/6/docs/api/java/text/DecimalFormat.html

DecimalFormat myFormatter = new DecimalFormat("###.###");

Upvotes: 0

Tassos Bassoukos
Tassos Bassoukos

Reputation: 16142

Use DecimalFormat with a format pattern string.

Upvotes: 0

Bozho
Bozho

Reputation: 597106

There are many ways to do that:

Upvotes: 3

Related Questions