zookastos
zookastos

Reputation: 935

Regex to detect numbers but not decimal

I am creating a formatter, which formats pricing. The idea is that if a user types 'between 45 and 50', it should return 'between $45.00 and $50.00'. Or if a user types 'between 45.58 to 38.91', it should return 'between $45.58 to $38.91'

This is what I have so far -

function formatPricesInString($str){
    var x = $str.match(/\d+/g);
    if(x != null){
        $.each(x, function(i, v){
            $str = $str.replace(v, formatPrice(v));
        });
    }
    return $str;
}

Here formatPrice(v) is another function to which if you pass 45, it will return $45.00.

Now, to my function - formatPricesInString($str), if I pass 45 - 50, it returns $45.00 - $50.00, which is fine, but if I pass 45.00 - 50.00 it is returning $45.00.$00.00 - $50.00.$00.00.

Basically, it is taking all the numbers - 45, 00, 50, 00 and formatting them.

How can I handle such scenario that if 45.00 or 45.56 is passed, it should not do anything, but if I just pass normal integer in the string, it should return formatted price.

Any other optimized way is also welcome.

formatPrice(...) method -

function formatPrice(price) {
    var symbol = $("#currencySymbolData").attr('data-symbol');
    if (typeof symbol === "undefined" || symbol == '') {
        symbol = '$';
    }
    var symbol_loc = $("#currencySymbolData").attr('data-symbol-loc');
    if (typeof symbol_loc === "undefined" || symbol_loc == '') {
        symbol_loc = 'before';
    }
    price = precise_round(price, 2).toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
    if (symbol_loc == 'after') {
        return price + symbol;
    } else {
        return symbol + price;
    }
}

EDIT - Answer

With the help of code provided by @RomanPerekhrest this worked -

function formatPricesInString($str){
    return $str.replace(/(\$?\d+(\.\d+)?)\b/g, function(m){
        m = (m[0] === '$')? m.slice(1) : m;
        return formatPrice(m);
    });
}

Upvotes: 2

Views: 117

Answers (1)

RomanPerekhrest
RomanPerekhrest

Reputation: 92854

Consider the following solution using String.prototype.replace() function with replacement callback:

var str = 'between 45 and 50 and between 45.58 to $38.91',
    formatted = str.replace(/(\$?\d+(\.\d+)?)\b/g, function (m) {
        var prefix = (m[0] === '$')? '' : '$';
        return prefix + ((m.indexOf('.') === -1)? Number(m).toFixed(2) : m);
    });

console.log(formatted);

Upvotes: 1

Related Questions