DecimalFormat преобразует числа с нецифрами

Использование DecimalFormat не дает исключения при разборе при использовании такого числа:

123привет

что, очевидно, на самом деле не является числом и преобразуется в значение 123,0. Как я могу избежать такого поведения?

В качестве примечания hello123 дает исключение, и это правильно.

Спасибо, Марсель


person marcel    schedule 06.07.2011    source источник
comment
Посмотрите на этот stackoverflow.com/ вопросы/4324997/   -  person Michael Konietzka    schedule 06.07.2011


Ответы (3)


Чтобы выполнить точный разбор, вы можете использовать

public Number parse(String text,
                ParsePosition pos)

Инициализируйте pos равным 0, и когда он будет завершен, он даст вам индекс после последнего использованного символа.

Затем вы можете сравнить это с длиной строки, чтобы убедиться, что синтаксический анализ был точным.

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

person Kal    schedule 06.07.2011
comment
Только жаль, что API не позволяет сделать что-то вроде этого: decimalFormat.setStrict(true) (строгий смысл не разрешать 123hello как число). Дело в том, что вы не всегда можете сами контролировать вызов парсинга. Другие библиотеки могут использовать объект формата. Большое спасибо за ответ! - person marcel; 07.07.2011

Расширяя ответ @Kal, вот служебный метод, который вы можете использовать с любым средством форматирования для «строгого» синтаксического анализа (использует StringUtils apache commons):

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;
}
person jtahlborn    schedule 06.07.2011

Вы можете проверить, что это числовое значение, используя RegEx:

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));
}
person Martijn Courteaux    schedule 06.07.2011
comment
Ваш код не приносит ничего, кроме Double.parseDouble(123hello). И точка DecimalFormat состоит в том, чтобы анализировать интернационализированные числа. 123 456,78 – допустимое десятичное число во французском языке. - person JB Nizet; 06.07.2011
comment
@JB: действительно, я хотел быть слишком быстрым :D - person Martijn Courteaux; 06.07.2011