Удалить конечный ноль в Java

У меня есть строки (из БД), которые могут содержать числовые значения. Если он содержит числовые значения, я хотел бы удалить конечные нули, например:

  • 10.0000
  • 10.234000

str.replaceAll("\\.0*$", "") работает на первом, но не на втором.

Многие ответы указывают на использование BigDecimal, но String я получаю не может быть числовым. Поэтому я думаю, что лучшее решение, вероятно, происходит через Regex.

Ответ 1

Есть возможности:

1000    -> 1000
10.000  -> 10 (without point in result)
10.0100 -> 10.01 
10.1234 -> 10.1234

Я ленивый и глупый, просто

s = s.indexOf(".") < 0 ? s : s.replaceAll("0*$", "").replaceAll("\\.$", "");

То же решение, использующее contains вместо indexOf, как упомянуто в некоторых комментариях для простоты понимания

 s = s.contains(".") ? s.replaceAll("0*$","").replaceAll("\\.$","") : s

Ответ 2

Используйте DecimalFormat, его самый чистый способ

String s = "10.1200";
DecimalFormat decimalFormat = new DecimalFormat("0.#####");
String result = decimalFormat.format(Double.valueOf(s));
System.out.println(result);

Ответ 3

Я нахожу все другое решение слишком сложным. Просто

s.replaceFirst("\\.0*$|(\\.\\d*?)0+$", "$1");

выполняет эту работу. Сначала он пробует первый вариант, так что точка, за которой следуют все нули, заменяется ничем (поскольку группа не получает набор). В противном случае, если он найдет точку, за которой последуют некоторые цифры (как можно меньше из-за ленивого квантификатора *?), за которым следуют некоторые нули, нули будут отброшены, поскольку они не включены в группу. Он работает.

Предупреждение

Мой код полагается на мое предположение что добавление непревзойденной группы ничего не делает. Это справедливо для реализации Oracle, но не для других, включая Android, которые, похоже, добавляют строку "null". Я бы назвал такие реализации сломанными, поскольку это просто не имеет смысла, но они правильные в соответствии с Javadoc.

Ответ 4

String value = "10.010"
String s = new DecimalFormat("0.####").format(Double.parseDouble(value));
System.out.println(s);

Output:

   10.01

Ответ 5

Ответ манипулятора в стиле Kent волшебным образом работает, а также удовлетворяет точность потерь, но здесь более чистое решение с использованием BigDecimal

String value = "10.234000";
BigDecimal stripedVal = new BigDecimal(value).stripTrailingZeros();

Затем вы можете преобразовать в другие типы

String stringValue = stripedVal.toPlainString();
double doubleValue = stripedVal.doubleValue();
long longValue = stripedVal.longValue();

Если потеря точности является для вас окончательной проблемой, тогда получите точное примитивное значение. Это приведет к исключению ArithmeticException, если будет некоторая потеря точности для примитива. См. Ниже

int intValue = stripedVal.intValueExact();

Ответ 6

Следующее работает для всех следующих примеров:

"1" -> "1"
"1.0" -> "1"
"1.01500" -> "1.015"
"1.103" -> "1.103"

s = s.replaceAll("()\\.0+$|(\\..+?)0+$", "$2");

Ответ 7

Как насчет замены

(\d*\.\d*)0*$

по

\1

?

Ответ 8

Вы можете заменить на:

String result = (str.indexOf(".")>=0?str.replaceAll("\\.?0+$",""):str);

Чтобы поддерживать регулярное выражение как можно проще. (И учетные данные, такие как 1000, как указано в комментариях)

Ответ 9

Моя реализация с возможностью выбора цифр после делителя:

public static String removeTrailingZero(String number, int minPrecise, char divider) {
    int dividerIndex = number.indexOf(divider);

    if (dividerIndex == -1) {
        return number;
    }

    int removeCount = 0;
    for (int i = dividerIndex + 1; i < number.length(); i++) {
        if (number.charAt(i) == '0') {
            removeCount++;
        } else {
            removeCount = 0;
        }
    }

    int fracLen = number.length() - dividerIndex - 1;

    if (fracLen - removeCount < minPrecise) {
        removeCount = fracLen - minPrecise;
    }

    if (removeCount < 0) {
        return number;
    }

    String result = number.substring(0, number.length() - removeCount);

    if (result.endsWith(String.valueOf(divider))) {
        return result.substring(0, result.length() - 1);
    }

    return result;
}

Ответ 10

.replaceFirst("\\.0*$|(\\.\\d*[1-9])0+$", "$1")

Ответ 11

Сначала отделите часть дроби. Затем вы можете использовать следующую логику.

BigDecimal value = BigDecimal.valueOf(345000);
BigDecimal div = new BigDecimal(10).pow(Integer.numberOfTrailingZeros(value.intValue()));
System.out.println(value.divide(div).intValue());