删除Java中的尾随零

删除Java中的尾随零,java,regex,string,Java,Regex,String,我有字符串(来自DB),其中可能包含数值。如果它包含数值,我希望删除尾随的零,例如: 10.0000 10.234000 str.replaceAll(“\\.0*$”,”)适用于第一个,但不适用于第二个 很多答案都指向使用BigDecimal,但我得到的字符串可能不是数字。因此,我认为更好的解决方案可能是通过正则表达式。替换正则表达式怎么样 (\d*\.\d*)0*$ 借 ?您可以替换为: String result = (str.indexOf(".")>=0?str.repl

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

  • 10.0000
  • 10.234000
str.replaceAll(“\\.0*$”,”)
适用于第一个,但不适用于第二个

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

替换正则表达式怎么样

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


您可以替换为:

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

使正则表达式尽可能简单。(并考虑注释中指出的输入,如
1000

存在以下可能性:

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("\\.$", "");

使用最干净的方式十进制格式

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

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

s.replaceFirst("\\.0*$|(\\.\\d*?)0+$", "$1");
他做这项工作。它首先尝试第一个备选方案,这样后面跟全零的点将被零替换(因为组未设置)。否则,如果它发现一个点后跟一些数字(由于惰性量词
*?
,所以尽可能少)再跟一些零,这些零将被丢弃,因为它们不包括在组中

警告
我的代码依赖于我的。对于Oracle实现,这是正确的,但对于其他实现,包括Android,它似乎附加了字符串“null”。我会称这些实现为中断,因为这可能毫无意义,但它们是。

首先分离出部分。然后您可以使用以下逻辑

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

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

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

s = s.replaceAll("()\\.0+$|(\\..+?)0+$", "$2");
字符串操作的答案神奇地工作,也迎合精度损失,但这里有一个更干净的解决方案使用BigDecimal

String value = "10.234000";
BigDecimal stripedVal = new BigDecimal(value).stripTrailingZeros();
然后可以转换为其他类型

String stringValue = stripedVal.toPlainString();
double doubleValue = stripedVal.doubleValue();
long longValue = stripedVal.longValue();
如果精度损失是您最关心的问题,请获取准确的原始值。如果原语有任何精度损失,这将抛出算术异常。见下文

int intValue = stripedVal.intValueExact();

我的实现可以选择除法器后的位数:

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;
}
publicstaticstringremovetrailingzero(字符串编号、整数、字符分隔符){
int dividerIndex=数字。indexOf(除法器);
if(dividerIndex==-1){
返回号码;
}
int removeCount=0;
对于(int i=dividerIndex+1;i
除了肯特的回答之外

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

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

只需将字符串转换为整数,然后再转换回字符串。@David:这会切割所有非整数。是否要使用java内置函数?这与第一个示例有问题。对。我只是想到了“尾随零”。而不是数字的数学表示。我的错。在这种情况下,Kent的答案(在应用正则表达式之前检查“.”更为正确。当然也是最慢的(甚至可能是最复杂的?)。@maaartinus为什么这么复杂?作为一个不太了解正则表达式的人,我可以理解这段代码,并根据需要进行调整。Regex可能更快,但就语法而言,这对我来说简直是一团糟。@TheLoverter再想一想,我基本上同意你的看法。正则表达式实际上非常简单(我建议在这个级别学习正则表达式),但更复杂的正则表达式会变得太混乱太快。一个正则表达式就足够了,请参见我的答案。您可以用
替换
s.indexOf(“.”<0
)!s、 为清晰起见,包含(“.”
。@Project
contains()
indexOf()
正在做完全相同的事情。您可以检查
contains()
@Kent“为了清晰起见”@Sergey我在我的眼睛JRE中运行代码,它适用于
0.0
6.0
什么是$1?它将null添加到我的String@RohanKandwal
$1
matcher.group(1)
,但您的测试用例是什么?正如您所见,我有很多测试用例,它们都可以工作。@Everett也有任何输入吗?这可能是错误的,但是输出对于发现问题是非常无用的。@maaartinus:看看他们的配置文件,他们可能在Android上执行代码。您好,虽然这可能很好地回答了这个问题,但请注意,其他用户可能没有您的知识渊博。你为什么不加一点解释,解释一下这段代码的工作原理呢?谢谢以上解决方案不适用于我的890.0我得到890空
int intValue = stripedVal.intValueExact();
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;
}
s = if (s.contains(".")) 
        s.replace(Regex("0*\$"),"").replace(Regex("\\.\$"),"") 
    else s