以下是Exception的结果:

String p="1,234";
Double d=Double.valueOf(p); 
System.out.println(d);


是否有比"1,234"更好的方法来解析1.234以获得p = p.replaceAll(",",".");

评论

以我的经验,如您所建议,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不,格式没有错误。一些语言环境使用逗号作为千位分隔符,因此您可以在一个数字中使用多个逗号,并且从技术上讲,这仍然是有效的输入。

#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