Exception
的结果:String p="1,234";
Double d=Double.valueOf(p);
System.out.println(d);
是否有比
"1,234"
更好的方法来解析1.234
以获得p = p.replaceAll(",",".");
?#1 楼
使用java.text.NumberFormat:NumberFormat format = NumberFormat.getInstance(Locale.FRANCE);
Number number = format.parse("1,234");
double d = number.doubleValue();
更新:
要支持多语言应用程序,请使用:
NumberFormat format = NumberFormat.getInstance(Locale.getDefault());
评论
仅当当前默认语言环境恰好使用逗号作为小数点分隔符时,此方法才有效。
–乔纳斯·普拉卡(Joonas Pulakka)
2010-12-01 11:05
为了进一步解决问题,某些语言环境使用逗号作为千位分隔符,在这种情况下,“ 1,234”将解析为1234.0而不是抛出错误。
–乔纳斯·普拉卡(Joonas Pulakka)
2010-12-01 11:11
NumberFormat的问题在于它将静默忽略无效字符。因此,如果您尝试解析“ 1,23abc”,它将很高兴返回1.23,而没有向您指示传入的String包含不可解析的字符。在某些情况下,这实际上可能是理想的,但我认为这通常不是理想的行为。
– E-Riz
2013年1月17日19:37
对于TURKEY,您应该使用NumberFormat.getInstance(new Locale(tr_TR))
–GünayGültekin
13年7月27日在9:45
有关谁使用分隔符的信息,请参见en.wikipedia.org/w/…
–脆弱
2014年11月21日7:09
#2 楼
您可以使用它(法语语言环境中的小数点分隔符为,
)NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE);
nf.parse(p);
或者可以使用
java.text.DecimalFormat
并设置适当的符号: DecimalFormat df = new DecimalFormat();
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setDecimalSeparator(',');
symbols.setGroupingSeparator(' ');
df.setDecimalFormatSymbols(symbols);
df.parse(p);
评论
是的...如果我们不设置千位分隔符,而仅使用法语格式,则西班牙语格式的数字(1.222.222,33)将被转换为“ 1 222 222,33”,这不是我想要的。那谢谢啦!
– WesternGun
17年3月30日14:55
另一件事是,西班牙语语言环境未列为“默认”,并且我无法使用新的Locale(“ es”,“ ES”)构造具有正确格式的语言环境,然后使用Number作为十进制分隔符自动解析具有NumberFormat的数字字符串和。作为千位分隔符,仅DecimalFormat有效。
– WesternGun
17 Mar 30 '15:11
为什么不是所有国家都在那里?我对使用法语语言环境设置波兰数字格式感到奇怪...
– Line
19年2月3日在21:23
#3 楼
正如E-Riz所指出的,NumberFormat.parse(String)将“ 1,23abc”解析为1.23。要获取全部输入,我们可以使用:public double parseDecimal(String input) throws ParseException{
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.getDefault());
ParsePosition parsePosition = new ParsePosition(0);
Number number = numberFormat.parse(input, parsePosition);
if(parsePosition.getIndex() != input.length()){
throw new ParseException("Invalid input", parsePosition.getIndex());
}
return number.doubleValue();
}
评论
此处详细说明了该策略:ibm.com/developerworks/library/j-numberformat
– Janus Varmarken
15年3月17日在21:56
#4 楼
Double.parseDouble(p.replace(',','.'))
...非常快,因为它逐个字符地搜索基础字符数组。字符串替换版本会编译一个RegEx进行评估。
基本上replace(char,char)快10倍左右,并且由于您将在低级代码中进行此类操作,因此有意义考虑一下。热点优化器不会弄清楚...当然不在我的系统上。
#5 楼
如果您不知道正确的语言环境,并且字符串可以有千位分隔符,那么这可能是最后的选择: “ R 1 52.43,2”到“ 15243.2”。#6 楼
这是我在自己的代码中使用的静态方法:public static double sGetDecimalStringAnyLocaleAsDouble (String value) {
if (value == null) {
Log.e("CORE", "Null value!");
return 0.0;
}
Locale theLocale = Locale.getDefault();
NumberFormat numberFormat = DecimalFormat.getInstance(theLocale);
Number theNumber;
try {
theNumber = numberFormat.parse(value);
return theNumber.doubleValue();
} catch (ParseException e) {
// The string value might be either 99.99 or 99,99, depending on Locale.
// We can deal with this safely, by forcing to be a point for the decimal separator, and then using Double.valueOf ...
//http://stackoverflow.com/questions/4323599/best-way-to-parsedouble-with-comma-as-decimal-separator
String valueWithDot = value.replaceAll(",",".");
try {
return Double.valueOf(valueWithDot);
} catch (NumberFormatException e2) {
// This happens if we're trying (say) to parse a string that isn't a number, as though it were a number!
// If this happens, it should only be due to application logic problems.
// In this case, the safest thing to do is return 0, having first fired-off a log warning.
Log.w("CORE", "Warning: Value is not a number" + value);
return 0.0;
}
}
}
评论
如果默认的语言环境类似于德语,逗号表示小数点后该怎么办?您可以传入,例如“ 1,000,000”,它不会解析为德语语言环境,然后将其替换为“ 1.000.000”,这不是有效的Double。
–艾迪·柯蒂斯(Eddie Curtis)
15年1月27日在17:01
@jimmycar,您好,我刚刚更新了答案,以使用当前版本的静态方法。希望这能解决您的问题!皮特
– Pete
2015年9月3日14:36在
#7 楼
您当然需要使用正确的语言环境。这个问题会有所帮助。#8 楼
如果您不知道接收到的字符串值的语言环境,并且不一定与当前默认语言环境相同,可以使用以下方法:private static double parseDouble(String price){
String parsedStringDouble;
if (price.contains(",") && price.contains(".")){
int indexOfComma = price.indexOf(",");
int indexOfDot = price.indexOf(".");
String beforeDigitSeparator;
String afterDigitSeparator;
if (indexOfComma < indexOfDot){
String[] splittedNumber = price.split("\.");
beforeDigitSeparator = splittedNumber[0];
afterDigitSeparator = splittedNumber[1];
}
else {
String[] splittedNumber = price.split(",");
beforeDigitSeparator = splittedNumber[0];
afterDigitSeparator = splittedNumber[1];
}
beforeDigitSeparator = beforeDigitSeparator.replace(",", "").replace(".", "");
parsedStringDouble = beforeDigitSeparator+"."+afterDigitSeparator;
}
else {
parsedStringDouble = price.replace(",", "");
}
return Double.parseDouble(parsedStringDouble);
}
无论字符串的语言环境是什么,它都会返回一个double值。而且无论有多少逗号或要点。因此,传递
1,000,000.54
将起作用,而1.000.000,54
也将起作用,因此您不必再依赖默认语言环境来解析字符串了。该代码没有得到最佳优化,因此欢迎您提出任何建议。我试图测试大多数情况,以确保它可以解决问题,但是我不确定它是否涵盖所有问题。如果您发现突破性的价值,请告诉我。 #9 楼
在Kotlin中,您可以使用以下扩展名:fun String.toDoubleEx() : Double {
val decimalSymbol = DecimalFormatSymbols.getInstance().decimalSeparator
return if (decimalSymbol == ',') {
this.replace(decimalSymbol, '.').toDouble()
} else {
this.toDouble()
}
}
,并且可以在代码中的任何地方使用它,如下所示:
val myNumber1 = "5,2"
val myNumber2 = "6.7"
val myNum1 = myNumber1.toDoubleEx()
val myNum2 = myNumber2.toDoubleEx()
这是简单且通用的!
#10 楼
这样就可以了:Double.parseDouble(p.replace(',','.'));
评论
最初的问题是:“有没有比“ p = p.replaceAll(“,”,“。”);来解析“ 1,234”以获得1.234更好的方法,如果您认为replace与使用replaceAll明显不同,请解释为什么。
–SuperBiasedMan
15年8月5日在9:24
评论
以我的经验,如您所建议,replaceAll()是执行此操作的最佳方法。它不依赖于当前语言环境,它很简单,并且可以正常工作。@Marco Altieri:replaceAll(“,”,“。”)用点替换所有逗号。如果没有逗号,则不执行任何操作。 Double.valueOf()(仅)适用于使用点作为小数点分隔符的字符串。当前的默认语言环境不会影响此处的任何内容。 docs.oracle.com/javase/8/docs/api/java/lang / ...
replaceAll(“,”,“。”)的唯一问题是,它只有在有一个逗号的情况下才有效:即:1,234,567将抛出java.lang.NumberFormatException:多点。正向查找的正则表达式足以满足p.replaceAll(“,(?= [0-9] +,)”,“”).replaceAll(“,”,“。”)更多信息:regular-expressions.info/lookaround .html
没有问题。 NumberFormatException是好的。您怎么知道哪个逗号是正确的?格式错误,您所能做的就是向用户显示比对异常更好的可读性消息。
@TheincredibleJan不,格式没有错误。一些语言环境使用逗号作为千位分隔符,因此您可以在一个数字中使用多个逗号,并且从技术上讲,这仍然是有效的输入。