48

我有字符串(来自 DB),其中可能包含数值。如果它包含数值,我想删除尾随零,例如:

  • 10.0000
  • 10.234000

str.replaceAll("\\.0*$", ""), 适用于第一个,但不适用于第二个。

很多答案都指向使用BigDecimal,但String我得到的可能不是数字。所以我认为更好的解决方案可能是通过正则表达式。

4

11 回答 11

97

有几种可能:

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
于 2013-02-20T16:42:50.830 回答
26

使用DecimalFormat,它最干净的方式

String s = "10.1200";
DecimalFormat decimalFormat = new DecimalFormat("0.#####");
String result = decimalFormat.format(Double.valueOf(s));
System.out.println(result);
于 2013-02-20T19:50:29.617 回答
12

肯特的字符串操作答案神奇地起作用并且还迎合精度损失,但这是使用 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();
于 2017-06-16T12:47:30.387 回答
11
String value = "10.010"
String s = new DecimalFormat("0.####").format(Double.parseDouble(value));
System.out.println(s);

Output:

   10.01
于 2015-04-13T10:49:27.850 回答
7

我发现所有其他解决方案都太复杂了。简单地

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

做这项工作。它首先尝试第一个替代方案,因此后跟全零的点会被任何内容替换(因为未设置组)。否则,如果它找到一个点后跟一些数字(由于惰性量词而尽可能少*?),然后是一些零,则这些零将被丢弃,因为它们不包含在组中。它有效

警告

我的代码依赖于我的假设,即附加一个不匹配的组什么都不做。这适用于 Oracle 实现,但不适用于其他实现,包括Android,它们似乎附加了字符串“null”。我认为这些实现被破坏了,因为它可能没有意义,但根据 Javadoc 它们是正确的

于 2014-06-13T20:04:48.230 回答
2

以下适用于以下所有示例:

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

s = s.replaceAll("()\\.0+$|(\\..+?)0+$", "$2");
于 2016-03-08T14:07:35.753 回答
0

换了怎么办

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

经过

\1

?

于 2013-02-20T16:20:19.287 回答
0

您可以替换为:

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

使正则表达式尽可能简单。(并考虑1000评论中指出的输入)

于 2013-02-20T16:23:20.537 回答
0

我的实现有可能在除法器后选择位数:

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;
}
于 2018-10-12T12:54:23.787 回答
0

除了肯特的回答。

小心Kotlin中的正则表达式。您必须手动编写Regex()构造函数而不是简单的字符串!

s = if (s.contains(".")) 
        s.replace(Regex("0*\$"),"").replace(Regex("\\.\$"),"") 
    else s
于 2020-04-25T06:54:37.167 回答
-1

先分离出分数部分。然后你可以使用下面的逻辑。

BigDecimal value = BigDecimal.valueOf(345000);
BigDecimal div = new BigDecimal(10).pow(Integer.numberOfTrailingZeros(value.intValue()));
System.out.println(value.divide(div).intValue());
于 2014-08-19T21:59:14.420 回答