দশমিক বিভাজক হিসাবে কমা দিয়ে পার্সড করার সর্বোত্তম উপায়?


148

নিম্নলিখিত একটি ফলাফল Exception:

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

সেখানে বিশ্লেষণ করতে একটি ভাল উপায় আছে "1,234"পেতে 1.234চেয়ে: p = p.replaceAll(",",".");?


17
আমার অভিজ্ঞতায়, প্রতিস্থাপন হিসাবে সমস্ত () প্রতিস্থাপন করা হ'ল এটি করার সর্বোত্তম উপায়। এটি বর্তমান লোকেলের উপর নির্ভর করে না, এটি সাধারণ, এবং এটি কাজ করে।
জুনাস পুলাক্কা

1
@ মার্কো আলটিয়ারি: replaceAll(",",".")সমস্ত কমাগুলি বিন্দু দিয়ে প্রতিস্থাপন করে। যদি কোনও কমা না থাকে তবে এটি কিছুই করে না। Double.valueOf()দশমিক বিভাজক হিসাবে ডট ব্যবহার করে এমন স্ট্রিংগুলির সাথে (কেবল) কাজ করে। এখানে বিদ্যমান কিছুই ডিফল্ট লোকাল দ্বারা প্রভাবিত হয় না। docs.oracle.com/javase/8/docs/api/java/lang/…
জুনাস পুলক্কা

4
একমাত্র সমস্যাটি replaceAll(",",".")হ'ল কেবলমাত্র একটি কমা থাকলে এটি কাজ করবে: যেমন: 1,234,567 নিক্ষেপ করবে java.lang.NumberFormatException: multiple points। ইতিবাচক চেহারা সহ একটি রেইজেক্স যথেষ্ট হবে p.replaceAll(",(?=[0-9]+,)", "").replaceAll(",", ".")আরও: নিয়মিত- এক্সপ্রেশন.নোফো
আর্টেমিসিয়ান

2
কোন সমস্যা নেই. নাম্বার ফর্ম্যাট এক্সেক্সশন ভাল good আপনি কীভাবে জানতে পারবেন কোনটি কমাটি সঠিক? ফর্ম্যাটটি ভুল এবং আপনি যা করতে পারেন তা ব্যবহারকারীর ব্যতিক্রমের চেয়ে আরও ভাল পঠনযোগ্য বার্তা দেখানো।
অবিশ্বাস্য

2
@The IncredibleJan না, ফর্ম্যাটটি ভুল নয়। কিছু লোকেল হাজার হাজার বিভাজক হিসাবে কমা ব্যবহার করে, যাতে কোনও সংখ্যায় আপনি এর মধ্যে একটির বেশি থাকতে পারেন এবং এটি প্রযুক্তিগতভাবে এখনও একটি বৈধ ইনপুট রয়েছে।
ভ্রতিস্লাভ জিন্দ্রা

উত্তর:


206

Java.text.Number Format ব্যবহার করুন :

NumberFormat format = NumberFormat.getInstance(Locale.FRANCE);
Number number = format.parse("1,234");
double d = number.doubleValue();

11
এটি কেবলমাত্র তখনই কাজ করে যদি বর্তমান ডিফল্ট লোকেল দশমিক বিভাজক হিসাবে কমা ব্যবহার করতে ঘটে।
জুনাস পুলক্কা

6
গণ্ডগোলের বিষয়গুলি আরও জানাতে , কিছু লোকেল হাজার হাজার বিভাজক হিসাবে কমা ব্যবহার করে , এই ক্ষেত্রে "1,234" ত্রুটি ছোঁড়ার পরিবর্তে 1234.0 এ পার্স করে।
জুনাস পুলক্কা

17
নাম্বার ফর্ম্যাট সমস্যাটি হ'ল এটি চুপচাপ অবৈধ অক্ষরগুলিকে উপেক্ষা করবে। সুতরাং যদি আপনি "1,23abc" কে বিশ্লেষণ করার চেষ্টা করেন তবে এটি আপনাকে সুস্পষ্টভাবে 1.23 প্রদান করবে যে আপনাকে এই নির্দেশ না দিয়েই উত্তীর্ণ হয়েছে যে স্ট্রিং-এ উত্তীর্ণযোগ্য অক্ষর রয়েছে। কিছু পরিস্থিতিতে প্রকৃতপক্ষে কাঙ্ক্ষিত হতে পারে তবে আমি সাধারণত এটি পছন্দসই আচরণ বলে মনে করি না।
ই-রিজ

7
তুরস্কের জন্য আপনার নাম্বার ফর্ম্যাট.গেট ইন্স্ট্যান্স (নতুন লোকেল (
টিআরটিআর

2
যারা ব্যবহার জন্য SEPERATOR কি দেখতে en.wikipedia.org/w/...
fiffy

67

আপনি এটি ব্যবহার করতে পারেন (ফরাসী লোকাল ,দশমিক বিভাজকের জন্য রয়েছে)

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" তে রূপান্তরিত হবে, যা আমি চাই না । সূতরাং ধন্যবাদ!
ওয়েস্টার্নগুন

1
আরেকটা জিনিস, স্প্যানিশ লোকেল হিসাবে "default` তালিকাভুক্ত করা হয় না এবং আমি একটি গঠন করা যায় না Localeসঙ্গে সঠিক বিন্যাসে সঙ্গে new Locale("es", "ES")এবং তারপর স্বয়ংক্রিয়ভাবে সঙ্গে সংখ্যা স্ট্রিং পার্স NumberFormatসঙ্গে, ,দশমিক হিসেবে বিভাজক এবং .সহস্র গ্রুপ বিভাজক হিসেবে শুধুমাত্র। DecimalFormatকাজ করে।
WesternGun

কেন সব দেশ সেখানে উপলব্ধ নয়? পোলিশ সংখ্যার ফর্ম্যাট করার জন্য ফরাসি লোকাল ব্যবহার করা সম্পর্কে আমি নিজেকে অদ্ভুত বোধ করি ...
লাইনে

18

ই-রিজ যেমন উল্লেখ করেছেন, সংখ্যাফর্ম্যাট.পারস (স্ট্রিং) "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();
}

2
এই কৌশলটি এখানে বিশদে
জানুস ভারমারকেন

7
Double.parseDouble(p.replace(',','.'))

... এটি চার্জ-বাই-চর ভিত্তিতে অন্তর্নিহিত অক্ষরের অ্যারেটি অনুসন্ধান করার সাথে সাথে এটি খুব দ্রুত। স্ট্রিং প্রতিস্থাপনের সংস্করণগুলি মূল্যায়নের জন্য একটি রেজিএক্স সংকলন করে।

মূলত প্রতিস্থাপন (চর, চর) প্রায় 10 গুণ দ্রুত এবং আপনি নিম্ন-স্তরের কোডগুলিতে এই ধরণের জিনিসগুলি করছেন তাই এটি সম্পর্কে চিন্তাভাবনা করা বোধগম্য। হট স্পট অপটিমাইজার এটি খুঁজে পাবে না ... অবশ্যই আমার সিস্টেমে নেই।


4

আপনি যদি সঠিক লোকেল না জানেন এবং স্ট্রিংটিতে হাজার বিভাজক থাকতে পারে এটি একটি শেষ অবলম্বন হতে পারে:

    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(",", "."));

সচেতন থাকুন: এটি "R 1 52.43,2" থেকে "15243.2" এর মতো স্ট্রিংগুলি আনন্দের সাথে পার্স করবে।


4

এটি আমি নিজের কোডে স্থির পদ্ধতি ব্যবহার করি:

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

5
ডিফল্ট লোকালে যদি জার্মানের মতো কিছু হয়, যেখানে কমা একটি দশমিক স্থানকে বোঝায়? আপনি পাস করতে পারেন, উদাহরণস্বরূপ "1,000,000" যা জার্মান লোকালে বিভক্ত হবে না এবং তারপরে "1.000.000" দ্বারা প্রতিস্থাপিত হবে যা বৈধ ডাবল নয়।
এডি কার্টিস

হাই @ জিম্মাইকার, আমি আমার স্থায়ী পদ্ধতির বর্তমান সংস্করণটি ব্যবহার করতে আমার উত্তরটি আপডেট করেছি। আমি আশা করি এটি আপনার সমস্যার সমাধান করে! পিট
পিট

1

আপনার অবশ্যই সঠিক লোকেল ব্যবহার করা দরকার। এই প্রশ্ন সাহায্য করবে।


0

আপনি যে স্ট্রিং মানটি পেয়েছেন তার লোকেলটি জানেন না এবং এটি বর্তমান ডিফল্ট লোকেলের মতো একই লোকেল নয় যা আপনি এটি ব্যবহার করতে পারেন:

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

}

স্ট্রিংয়ের লোকেল কী তা বিবেচনা না করে এটি একটি ডাবল ফিরিয়ে দেবে। এবং সেখানে কতগুলি কমা বা পয়েন্ট রয়েছে তা বিবেচনাধীন। পাসিং 1,000,000.54তাই কাজ করবে 1.000.000,54তাই আপনাকে স্ট্রিংটি বিশ্লেষণের জন্য আর ডিফল্ট লোকালে নির্ভর করতে হবে না। কোডটি যতটা অনুকূল হতে পারে তেমন কোনও প্রস্তাবনা স্বাগত। সমস্যাটি সমাধান হয়েছে কিনা তা নিশ্চিত করার জন্য আমি বেশিরভাগ ক্ষেত্রে পরীক্ষা করার চেষ্টা করেছি তবে আমি নিশ্চিত নই যে এটি সমস্তটি কভার করে। যদি আপনি কোনও ব্রেকিং মান খুঁজে পান তবে আমাকে জানান।


-5

এটি কাজ করবে:

Double.parseDouble(p.replace(',','.')); 

6
প্রাথমিক প্রশ্নটি বলেছিল "" ১.২৩৪ "পার্স করার আরও ভাল উপায় কি এর চেয়ে ১.২৩৪৪ পাওয়ার জন্য আছে: পি = পি.প্লেসরএল (", ","। ");" , যদি আপনি মনে replaceকরেন ব্যবহার থেকে উল্লেখযোগ্যভাবে পৃথক হয়ে থাকে replaceAllতবে দয়া করে কেন তা ব্যাখ্যা করুন।
সুপারবিসাইডমান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.