2011-12-07 5 views
7

Sprawdzam dane wejściowe użytkownika z formularza.Jak analizować liczby bardziej rygorystyczne niż to, co robi NumberFormat w Javie?

Analizuję dane wejściowe za pomocą NumberFormat, ale jest to złe i pozwala na prawie wszystko. Czy istnieje sposób na parsowanie liczb bardziej rygorystycznych?

E.g. Chciałbym, aby nie pozwolić na te trzy wejścia, do liczby całkowitej, ale Numberformat umożliwić wszystkie z nich:

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

jak o przekształcenie go na sznurku, a następnie zapętlaj ciąg znaków i zezwalaj tylko na znaki "0" .. "9"?lub po prostu przejdź do getIntegerInstance(); – ComputerSaysNo

+0

@DorinDuminica: 'getIntegerInstance()' daje taki sam wynik. – Jonas

+1

dlaczego nie używać 'Integer.parseInt (String)' –

Odpowiedz

1

Jeśli chcesz przeanalizować liczbę całkowitą składają opcjonalny „-”, a następnie 1 lub więcej cyfr po przecinku, a następnie

int num = Integer.parseInt(str); 

lub

long num = Long.parseLong(str); 

Jeśli chcesz po prostu sprawdzanie poprawności, a nie konwersję całkowitą, a następnie regex to kolejna alternatywa; na przykład

boolean ok = Pattern.compile("-?\\d+").matches(str); 
+0

Lub 'str.matches (" -? \\ d + ")' dla bardziej zwięzłych. –

0

Użyj DecimalFormat z ciągiem znaków formatowania.

+0

'DecimalFormat' ma ten sam problem z tym. A może masz przykład? – Jonas

2

Integer.parseInt(String) wyrzuci wyjątek NumberFormatException we wszystkich przykładach. Nie jestem pewien, czy tego właśnie szukasz, ale na pewno "bardziej rygorystycznie".

6

Może to pomoże:

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"); 
} 

(Dzięki Strict number parsing at mynetgear.net)

+0

Dziękuję - to jedyna prawdziwa odpowiedź! Drugi nie uwzględnia lokalnego (jak separator dziesiętny). Zastanawiam się, dlaczego to nie jest (przynajmniej konfigurowalne) w domyślnej implementacji :( – Rainer

0

nie będę używać formatu liczba rutynowych Java, zwłaszcza z lokalnych ustawień jeśli martwić walidacji.

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

Spodziewałbyś się tutaj problemu, ale nie ... test jest równy 2, a POS ma indeks 3 i indeks błędu -1.