我有字符串(来自 DB),其中可能包含数值。如果它包含数值,我想删除尾随零,例如:
10.0000
-
10.234000
str.replaceAll("\\.0*$", "")
, 适用于第一个,但不适用于第二个。
很多答案都指向使用BigDecimal
,但String
我得到的可能不是数字。所以我认为更好的解决方案可能是通过正则表达式。
有几种可能:
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
使用DecimalFormat,它最干净的方式
String s = "10.1200";
DecimalFormat decimalFormat = new DecimalFormat("0.#####");
String result = decimalFormat.format(Double.valueOf(s));
System.out.println(result);
肯特的字符串操作答案神奇地起作用并且还迎合精度损失,但这是使用 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();
String value = "10.010"
String s = new DecimalFormat("0.####").format(Double.parseDouble(value));
System.out.println(s);
Output:
10.01
我发现所有其他解决方案都太复杂了。简单地
s.replaceFirst("\\.0*$|(\\.\\d*?)0+$", "$1");
做这项工作。它首先尝试第一个替代方案,因此后跟全零的点会被任何内容替换(因为未设置组)。否则,如果它找到一个点后跟一些数字(由于惰性量词而尽可能少*?
),然后是一些零,则这些零将被丢弃,因为它们不包含在组中。它有效。
我的代码依赖于我的假设,即附加一个不匹配的组什么都不做。这适用于 Oracle 实现,但不适用于其他实现,包括Android,它们似乎附加了字符串“null”。我认为这些实现被破坏了,因为它可能没有意义,但根据 Javadoc 它们是正确的。
以下适用于以下所有示例:
"1" -> "1"
"1.0" -> "1"
"1.01500" -> "1.015"
"1.103" -> "1.103"
s = s.replaceAll("()\\.0+$|(\\..+?)0+$", "$2");
换了怎么办
(\d*\.\d*)0*$
经过
\1
?
您可以替换为:
String result = (str.indexOf(".")>=0?str.replaceAll("\\.?0+$",""):str);
使正则表达式尽可能简单。(并考虑1000
评论中指出的输入)
我的实现有可能在除法器后选择位数:
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;
}
除了肯特的回答。
小心Kotlin中的正则表达式。您必须手动编写Regex()
构造函数而不是简单的字符串!
s = if (s.contains("."))
s.replace(Regex("0*\$"),"").replace(Regex("\\.\$"),"")
else s
先分离出分数部分。然后你可以使用下面的逻辑。
BigDecimal value = BigDecimal.valueOf(345000);
BigDecimal div = new BigDecimal(10).pow(Integer.numberOfTrailingZeros(value.intValue()));
System.out.println(value.divide(div).intValue());