2011-07-06 8 views
12

Korzystanie DecimalFormat daje żadnego wyjątku składniowy podczas korzystania z tego rodzaju numeru:DecimalFormat konwertuje numery z non-cyfry

123hello

który oczywiście nie jest naprawdę wiele, i konwertuje do 123,0 wartości. Jak mogę uniknąć tego rodzaju zachowań?

Jako strona notatka hello123 daje wyjątek, który jest poprawny.

Dzięki Marcel

+0

Spójrz na to http://stackoverflow.com/questions/4324997/why-does-decimalformat-allow-characters-as-suffix –

Odpowiedz

9

Aby zrobić dokładną analizę składni, można użyć

public Number parse(String text, 
       ParsePosition pos) 

Initialize poz 0 i po jej zakończeniu to daje indeks po ostatnim znaku, który został użyty.

Następnie można porównać to z długością ciągu, aby upewnić się, że analiza była dokładna.

http://download.oracle.com/javase/1.4.2/docs/api/java/text/DecimalFormat.html#parse%28java.lang.String,%20java.text.ParsePosition%29

+1

tylko szkoda, że ​​API nie pozwala na zrobienie czegoś takiego: decimalFormat.setStrict (true) (ścisłe znaczenie nie pozwalające na 123hello jako numer). Chodzi o to, że nie zawsze możesz kontrolować wezwanie do parsowania się. Inne biblioteki mogą używać obiektu formatu. Wielkie dzięki za odpowiedź! – marcel

0

Można sprawdzić, że jest numeryczne za pomocą wyrażenia regularnego:

String input = "123hello"; 
double d = parseDouble(input); // Runtime Error 

public double parseDouble(String input, DecimalFormat format) throws NumberFormatException 
{ 
    if (input.equals("-") || input.equals("-.")) 
     throw NumberFormatException.forInputString(input); 
    if (!input.matches("\\-?[0-9]*(\\.[0-9]*)?")) 
     throw NumberFormatException.forInputString(input); 

    // From here, we are sure it is numeric. 
    return format.parse(intput, new ParsePosition(0)); 
} 
+2

Twój kod nie zawiera niczego innego niż Double.parseDouble ("123hello"). A punktem DecimalFormat jest analizowanie umiędzynarodowionych liczb. 123 456,78 to poprawna liczba dziesiętna w francuskim języku. –

+0

@JB: Rzeczywiście, chciałem być szybki: D –

+0

Dzięki za odpowiedź! – marcel

1

poszerzając @ odpowiedź Kal, oto jest metoda narzędzie, które można wykorzystać w dowolnym formater robić „surowe” parsowania (wykorzystuje apache Commons StringUtils):

public static Object parseStrict(Format fmt, String value) 
    throws ParseException 
{ 
    ParsePosition pos = new ParsePosition(0); 
    Object result = fmt.parseObject(value, pos); 
    if(pos.getIndex() < value.length()) { 
     // ignore trailing blanks 
     String trailing = value.substring(pos.getIndex()); 
     if(!StringUtils.isBlank(trailing)) { 
      throw new ParseException("Failed parsing '" + value + "' due to extra trailing character(s) '" + 
            trailing + "'", pos.getIndex()); 
     } 
    } 
    return result; 
} 
+0

Dzięki za odpowiedź! – marcel