Как обработать случай, когда неправильный ввод не вызывает ParseException при разборе локализованного номера? - PullRequest
0 голосов
/ 09 октября 2019

Дано:

Locale userLocale = Locale.forLanguageTag("uk-UK");
DecimalFormat decimalFormat = (DecimalFormat) NumberFormat.getInstance(userLocale);
decimalFormat.setParseBigDecimal(true);
System.out.println(decimalFormat.parse("123456,99").toString()); // output: 123456.99 -> it's OK
System.out.println(decimalFormat.parse("123456Test99").toString()); // output: 123456 -> it's BAD

Ожидается:

ParseException при последнем вводе.

  1. Почему бы не выполнить быструю проверку, выбранную разработчиками jdk?
  2. Как вы справляетесь с такими делами?

Моя текущая попытка:

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
import static java.lang.Character.isDigit;

private BigDecimal processNumber(DecimalFormat numberFormat, String rowValue) throws ParseException {
    BigDecimal value = null;
    if (rowValue == null) return null;
    final char groupingSeparator = numberFormat.getDecimalFormatSymbols().getGroupingSeparator();
    final char decimalSeparator = numberFormat.getDecimalFormatSymbols().getDecimalSeparator();
    final char minusSign = numberFormat.getDecimalFormatSymbols().getMinusSign();
    for (char ch : rowValue.toCharArray())
        if (!isDigit(ch) && ch != decimalSeparator && ch != groupingSeparator && ch != minusSign)
            throw new ParseException("", 0); // wrong pos, I know, but it's excessively here
    if (!rowValue.isEmpty())
        value = new BigDecimal(numberFormat.parse(rowValue).toString());
    return value;
}

1 Ответ

1 голос
/ 09 октября 2019

Ниже приведен пример, в котором я использовал ParsePosition, чтобы узнать, где закончился анализ. Если не вся входная строка была проанализирована, выводится ошибка.

String string1 = "123456,99";
String string2 = "123456Test99";

Locale userLocale = Locale.forLanguageTag("uk-UK");
DecimalFormat decimalFormat = (DecimalFormat) NumberFormat.getInstance(userLocale);
decimalFormat.setParseBigDecimal(true);

ParsePosition parsePosition = new ParsePosition(0);
Number number1 = decimalFormat.parse(string1, parsePosition);

if (parsePosition.getIndex() <= string1.length()) {
  System.out.println("Parse error");
} else {
  System.out.println(number1.toString());
}

parsePosition = new ParsePosition(0);
Number number2 = decimalFormat.parse(string2, parsePosition);

if (parsePosition.getIndex() <= string2.length()) {
  System.out.println("Parse error");
} else {
  System.out.println(number2.toString());
}

Сгенерированный вывод:

123456.99
Parse error
...