Thibstars
Thibstars

Reputation: 1083

How to properly format a number String

I'm looking for an efficient way to have number Strings properly formatted so it could be parsed to a double value.

Requirements:

Examples: 1.234.567,89 => 1234567.89; 5 => 5; 6.3 => 6.3; 5.23 => 5.23;...

To check if the String is a number, I'd like to user either regex or NumberUtils.isNumber(numberString). Only problem with the latter one is that it has issues with strings like "123,45".

My current attempt (that feels pretty inefficient):

    LOGGER.debug("Normalizing price string: " + price);
    String str = price;

    if (str.contains(",") || str.contains(".")) {

        int pos = -1;
        if (str.contains(",")) pos = str.lastIndexOf(',');
        else if (str.contains(".")) pos = str.lastIndexOf(".");

        //Remove all the dots and commas first
        str = str.replaceAll("[,.]", "");

        if (!NumberUtils.isNumber(str) || !NumberUtils.isDigits(str)) {
            LOGGER.debug("String does not match expected pattern");
            throw new NumberFormatException();
        } else {
            //Add a dot back in

            if (str.length() <= 2) {
                StringBuilder first = new StringBuilder(str.substring(0, pos));
                first.append('.');
                String last = str.substring(pos);
                str = first + last;
            } else {
                StringBuilder first = new StringBuilder(str.substring(0, str.length() - 2));
                first.append('.');
                String last = str.substring(str.length() - 2);

                str = first + last;
            }
        }
    }

    LOGGER.debug("Normalised result: " + str);
    return str;`

How can this formatting be simplified, made more efficient, and correctly handle incorrect input?

Applied solution

    String str = price;
    DecimalFormatSymbols dfsDot = new DecimalFormatSymbols();
    dfsDot.setDecimalSeparator('.');
    DecimalFormatSymbols dfsComma = new DecimalFormatSymbols();
    dfsComma.setDecimalSeparator(',');

    DecimalFormat dfDot = new DecimalFormat("#,##0.00", dfsDot);
    DecimalFormat dfComma = new DecimalFormat("#,##0.00", dfsComma);

    double d = 0;
    try {
        if (!str.contains(",") && !str.contains(".")) {
            return str;
        } else if (str.contains(",")) d = (Double) dfComma.parse(str);
        else if (str.contains(".")) d = (Double) dfDot.parse(str);
        str = "" + d;
    } catch (ParseException e) {
        LOGGER.debug(str + " couldn't be cast to Double");
        e.printStackTrace();
        return price;
    }

Upvotes: 0

Views: 152

Answers (1)

David P&#233;rez Cabrera
David P&#233;rez Cabrera

Reputation: 5048

Do you know DecimalFormat ?

DecimalFormatSymbols dfs =new DecimalFormatSymbols();
dfs.setDecimalSeparator('.');
DecimalFormat df = new DecimalFormat("#,##0.00",dfs);
double d = df.parse("123.45").doubleValue();
System.out.println(d);

It prints:

123.45

Upvotes: 3

Related Questions