【问题标题】:Remove trailing zero in Java删除 Java 中的尾随零
【发布时间】:2013-02-20 16:16:20
【问题描述】:

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

  • 10.0000
  • 10.234000

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

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

【问题讨论】:

  • 只需将字符串转换为int,然后再转换回字符串。
  • @David:所有非整数的切分。

标签: java regex string


【解决方案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 的解决方案与某些 cmets 中提到的相同,以便于理解

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

【讨论】:

  • 一个正则表达式就足够了,看我的回答。
  • 为了清楚起见,您可以将 s.indexOf(".") &lt; 0 替换为 !s.contains(".")
  • @Project contains()indexOf() 正在做同样的事情。可以查看contains()的实现@
  • @Kent “为了清楚起见”
  • @Sergey 我在我的 Eye-JRE 中运行代码,它适用于 0.06.0
【解决方案2】:

使用 DecimalFormat,这是最简洁的方式

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

【讨论】:

  • 当然也是最慢的(甚至可能是最复杂的?)。
  • @maaartinus 为什么这么复杂?作为一个不太了解正则表达式的人,我可以理解这段代码并根据我的需要进行调整。正则表达式可能更快,但在语法方面,这对我来说只是一团糟。
  • @TheWanderer 再想一想,我基本上同意你的看法。正则表达式实际上非常简单(我建议在这个级别学习正则表达式),但是更复杂的正则表达式会变得太混乱太快。
【解决方案3】:

Kent's 字符串操作答案神奇地起作用并且还可以满足精度损失,但这是使用 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();

【讨论】:

  • 不完全是 OP 所要求的(不适用于非数字值),但正是我所需要的 - 谢谢!
【解决方案4】:
String value = "10.010"
String s = new DecimalFormat("0.####").format(Double.parseDouble(value));
System.out.println(s);

Output:

   10.01

【讨论】:

  • 您好,虽然这可能很好地回答了这个问题,但请注意,其他用户可能不像您那样知识渊博。您为什么不添加一些关于此代码为何有效的解释?谢谢!
【解决方案5】:

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

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

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

警告

我的代码依赖于我的assumption that appending a unmatched group does nothing。这对于 Oracle 实现是正确的,但对于其他实现则不然,包括 Android,它们似乎附加了字符串“null”。我认为此类实现已损坏,因为它可能没有意义,但它们是 correct according to the Javadoc

【讨论】:

  • 1 美元是多少?它在我的字符串末尾添加了 null
  • @RohanKandwal $1matcher.group(1),但你的测试用例是什么?如您所见,我有很多测试用例,它们都有效。
  • @Everett 还有什么意见吗?这可能是错误的,但输出对于查找问题毫无用处。
  • @maaartinus:查看他们的个人资料,他们可能在 Android 上执行代码。
【解决方案6】:

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

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

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

【讨论】:

  • 以上解决方案不适用于 890.0 我得到 890null
【解决方案7】:

怎么换

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

通过

\1

?

【讨论】:

  • 有没有java内置函数可以使用?
  • 第一个例子有问题。
【解决方案8】:

您可以替换为:

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

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

【讨论】:

  • 对。我只是想到了“尾随零”。不是数字的数学表示。我的错。在这种情况下,Kent 的答案(在应用 Regex 之前检查“.”)更正确。
【解决方案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】:

    除了肯特的回答。

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

    s = if (s.contains(".")) 
            s.replace(Regex("0*\$"),"").replace(Regex("\\.\$"),"") 
        else s
    

    【讨论】:

      【解决方案11】:

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

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

      【讨论】:

        猜你喜欢
        • 2020-01-25
        • 2013-07-20
        • 2011-05-30
        • 2012-01-26
        • 1970-01-01
        • 1970-01-01
        • 2011-10-27
        • 2012-07-01
        • 2012-07-02
        相关资源
        最近更新 更多