简体   繁体   中英

Remove trailing zero in Java

I have Strings (from DB), which may contain numeric values. If it contains numeric values, I'd like to remove trailing zeros such as:

  • 10.0000
  • 10.234000

str.replaceAll("\\.0*$", "") , works on the first one, but not the second one.

A lot of the answers point to use BigDecimal , but the String I get may not be numeric. So I think a better solution probably is through the Regex.

there are possibilities:

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

I am lazy and stupid, just

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

Same solution using contains instead of indexOf as mentioned in some of the comments for easy understanding

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

Use DecimalFormat , its cleanest way

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

Kent's string manipulation answer magically works and also caters for precision loss, But here's a cleaner solution using BigDecimal

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

You can then convert to other types

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

If precision loss is an ultimate concern for you, then obtain the exact primitive value. This would throw ArithmeticException if there'll be any precision loss for the primitive. See below

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

Output:

   10.01

I find all the other solution too complicated. Simply

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

does the job. It tries the first alternative first, so that dot followed by all zeros gets replaced by nothing (as the group doesn't get set). Otherwise, if it finds a dot followed by some digits (as few as possible due to the lazy quantifier *? ) followed by some zeros, the zeros get discarded as they're not included in the group. It works .

Warning

My code relies on my assumption that appending a unmatched group does nothing . This is true for the Oracle implementation, but not for others, including Android , which seem to append the string "null". I'd call the such implementations broken as it just may no sense, but they're correct according to the Javadoc .

The following works for all the following examples:

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

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

What about replacing

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

by

\1

?

You could replace with:

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

To keep the Regex as simple as possible. (And account for inputs like 1000 as pointed out in comments)

My implementation with possibility to select numbers of digits after divider:

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;
}

In addition to Kent 's answer.

Be careful with regex in Kotlin . You have to manually write Regex() constructor instead of a simple string!

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

Try to use this code:

DecimalFormat df = new DecimalFormat("#0.#####");

String value1 = df.format(101.00000);
String value2 = df.format(102.02000);
String value3 = df.format(103.20000);
String value4 = df.format(104.30020);

Output:

101
102.02
103.2
104.3002

Separate out the fraction part first. Then you can use the below logic.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM