2013-01-07 7 views
7

Powiel możliwe:
Parsing numbers safely and locale-sensitivelySprawdzanie liczby dziesiętne w sposób wrażliwy locale w Java

Jak mogę potwierdzić ciągów znaków zawierających cyfry dziesiętne w sposób locale wrażliwe? NumberFormat.parse pozwala na zbyt wiele, a Double.parseDouble działa tylko dla angielskich ustawień narodowych. Oto, co starałem:

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 
} 
+0

Gdyby to wyjątek, jeśli locale jest niemiecki, a wejście jest '3.3' zamiast' 3,3'? – jlordo

+0

'Liczba przeanalizowana = liczbaFormat.parse (" 4.5.6dfhf ");' działa również i produkuje '456' ... Eurgh ... – assylias

+0

jlordo: przynajmniej powinien zaakceptować poprawne numery ... – WannaKnow

Odpowiedz

2

W odniesieniu Spośród

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

problem, można ewentualnie użyć NumberFormat.parse (źródło ciągu, ParsePosition poz) i sprawdź, czy pozycja, w której zatrzymał parsowanie, rzeczywiście była ostatnią pozycją ciągu.

Ponadto, w problemie 4.5.6 można spróbować ustawić grupowanie wyłączone przez setGroupingUsed (boolean newValue), ponieważ uważam, że jest to problem spowodowany przez "." znak będący znakiem grupującym w ustawieniach narodowych.

To powinno być coś jak

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 
+1

Ale to nadal akceptowałoby bzdury, takie jak "4.5.6". –

+0

Właściwie warunek if (nString.length() == pos.getIndex()) (bez odjęcia jednego od długości) wydaje się być właściwym warunkiem – WannaKnow

+0

Andreas_D: Myślę, że kropki są po prostu ignorowane, tak jak przecinki są ignorowane w przypadku języka angielskiego locale – WannaKnow

1

Od komentarzu powyżej, można użyć:

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

Jeśli separator może być coś innego oprócz przecinkiem, po prostu dodaj go w nawiasach kwadratowych:

double value = Double.parseDouble(input.replaceAll("[,]", ".")); 
+0

Problem polega na tym, że nie jest gwarantowane, że lokalizacja jest niemiecka.Może to być cokolwiek.Myślisz, że to zadziała dla dowolnego ustawienia narodowego? – WannaKnow

+0

Tak długo, jak separator jest kropka lub przecinek, to zadziała.Nie wiem o lokalizacji, gdzie separator jest czymś innym – jlordo

+0

Co powiesz na spacje? '1 000 000' jest prawdopodobnie poprawny w niektórych lokalizacjach. zależny parser brzmi jak niebezpieczna gra ... – assylias

Powiązane problemy