Aşağıdakiler bir Exception:
String p="1,234";
Double d=Double.valueOf(p);
System.out.println(d);
Ayrıştırmak için daha iyi bir yolu var mı "1,234"almak 1.234daha: p = p.replaceAll(",",".");?
Aşağıdakiler bir Exception:
String p="1,234";
Double d=Double.valueOf(p);
System.out.println(d);
Ayrıştırmak için daha iyi bir yolu var mı "1,234"almak 1.234daha: p = p.replaceAll(",",".");?
replaceAll(",",".")tüm virgülleri noktalarla değiştirir. Virgül yoksa, hiçbir şey yapmaz. Double.valueOf()ondalık ayırıcı olarak nokta kullanan dizelerle çalışır (yalnızca). Buradaki hiçbir şey geçerli varsayılan yerel ayardan etkilenmez. docs.oracle.com/javase/8/docs/api/java/lang/…
replaceAll(",",".")yalnızca tek bir virgül varsa işe yaramasıdır: yani: 1,234,567 atar java.lang.NumberFormatException: multiple points. Olumlu bakımlı bir normal ifade yeterli olacaktır p.replaceAll(",(?=[0-9]+,)", "").replaceAll(",", ".")Daha fazla bilgi için: normal-expressions.info/lookaround.html
Yanıtlar:
Java.text.NumberFormat kullanın :
NumberFormat format = NumberFormat.getInstance(Locale.FRANCE);
Number number = format.parse("1,234");
double d = number.doubleValue();
Güncellenmiş:
Çok dilli uygulamaları desteklemek için şunları kullanın:
NumberFormat format = NumberFormat.getInstance(Locale.getDefault());
Bunu kullanabilirsiniz (Fransız yerel ayarı ,ondalık ayırıcıya sahiptir)
NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE);
nf.parse(p);
Veya java.text.DecimalFormatuygun sembolleri kullanabilir ve ayarlayabilirsiniz:
DecimalFormat df = new DecimalFormat();
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setDecimalSeparator(',');
symbols.setGroupingSeparator(' ');
df.setDecimalFormatSymbols(symbols);
df.parse(p);
Localeile doğru formatta ile new Locale("es", "ES")ve daha sonra otomatik olarak birlikte sayı dizesini ayrıştırmak NumberFormatile, ,ondalık olarak ayırıcı ve .bin grup ayırıcı olarak yalnızca. DecimalFormatÇalışır.
E-Riz'in işaret ettiği gibi, NumberFormat.parse (String), "1,23abc" yi 1.23 olarak çözümler. Tüm girdiyi almak için kullanabiliriz:
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();
}
Double.parseDouble(p.replace(',','.'))
... temel karakter dizisini karakter bazında aradığından çok hızlıdır. Dize değiştirme sürümleri, değerlendirmek için bir RegEx derler.
Temel olarak replace (char, char) yaklaşık 10 kat daha hızlıdır ve bu tür şeyleri düşük seviyeli kodda yapacağınız için bunun hakkında düşünmek mantıklıdır. Hot Spot iyileştirici bunu çözmeyecek ... Benim sistemimde kesinlikle yok.
Doğru Yerel Ayarı bilmiyorsanız ve dizede bin ayırıcı varsa, bu son çare olabilir:
doubleStrIn = doubleStrIn.replaceAll("[^\\d,\\.]++", "");
if (doubleStrIn.matches(".+\\.\\d+,\\d+$"))
return Double.parseDouble(doubleStrIn.replaceAll("\\.", "").replaceAll(",", "."));
if (doubleStrIn.matches(".+,\\d+\\.\\d+$"))
return Double.parseDouble(doubleStrIn.replaceAll(",", ""));
return Double.parseDouble(doubleStrIn.replaceAll(",", "."));
Unutmayın: Bu, "R 1 52.43,2" ila "15243.2" gibi dizeleri mutlu bir şekilde ayrıştıracaktır.
Kendi kodumda kullandığım statik yöntem bu:
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;
}
}
}
Elbette doğru yerel ayarı kullanmanız gerekir. Bu soru yardımcı olacak.
Alınan dize değerinin yerel ayarını bilmediğiniz ve bunun geçerli varsayılan yerel ayar ile mutlaka aynı yerel ayar olmadığı durumlarda, bunu kullanabilirsiniz:
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);
}
Dizenin yeri ne olursa olsun bir double döndürür. Ve kaç tane virgül veya nokta olduğu önemli değil. Bu yüzden geçiş yapmak 1,000,000.54da işe yarayacaktır, 1.000.000,54böylece artık dizeyi ayrıştırmak için varsayılan yerel ayara güvenmek zorunda kalmazsınız. Kod olabildiğince optimize edilmemiştir, bu nedenle herhangi bir öneriye açığız. Sorunu çözdüğünden emin olmak için vakaların çoğunu test etmeye çalıştım, ancak hepsini kapsadığından emin değilim. Bir kırılma değeri bulursanız bana bildirin.
Kotlin'de aşağıdaki uzantıları kullanabilirsiniz:
fun String.toDoubleEx() : Double {
val decimalSymbol = DecimalFormatSymbols.getInstance().decimalSeparator
return if (decimalSymbol == ',') {
this.replace(decimalSymbol, '.').toDouble()
} else {
this.toDouble()
}
}
ve bunu kodunuzun her yerinde şu şekilde kullanabilirsiniz:
val myNumber1 = "5,2"
val myNumber2 = "6.7"
val myNum1 = myNumber1.toDoubleEx()
val myNum2 = myNumber2.toDoubleEx()
Kolay ve evrenseldir!
Bu işi yapacaktı:
Double.parseDouble(p.replace(',','.'));
replacekullanmaktan önemli ölçüde farklı olduğunu düşünüyorsanız replaceAll, lütfen nedenini açıklayın.