298

I have a text box that will have a currency string in it that I then need to convert that string to a double to perform some operations on it.

"$1,100.00"1100.00

This needs to occur all client side. I have no choice but to leave the currency string as a currency string as input but need to cast/convert it to a double to allow some mathematical operations.

João Pimentel Ferreira
  • 14,289
  • 10
  • 80
  • 109
Bobby Borszich
  • 11,639
  • 9
  • 37
  • 35
  • 1. This question could benefit from a list of test strings (or input bounds) to validate any answer against. 2. Currency + JS float behavior appears to be **edge case risky**, maybe not pain level of date/time programming but more than might expect -- Consider a library, a built-in, or a custom function accepting narrowly bounded inputs to avoid getting unexpected `NaN` or other errors. – PotatoFarmer Dec 19 '22 at 22:48
  • You don't want to use floating point for this, but fixed point. I'm new to JS, so I can't provide more detailed information at the present time about this. – FreelanceConsultant Feb 06 '23 at 20:52

25 Answers25

587

Remove all non dot / digits:

var currency = "-$4,400.50";
var number = Number(currency.replace(/[^0-9.-]+/g,""));
Matt McCutchen
  • 28,856
  • 2
  • 68
  • 75
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • 6
    It seems this only works where there is a `.00` trailing. Otherwise valid representations of currency such as "$1100" and "$1100." will be reduced by two orders of magnitude. – Brian M. Hunt Feb 08 '13 at 00:43
  • 34
    Keep in mind that this is locale-dependent, as other locales use ',' for decimals (e.g. 1.100,00€). Some other locales even use different standard number of digits per group (like 3 decimals). – smola Mar 22 '13 at 07:55
  • 10
    To handle negative numbers in the string, I added a '-' to the list of chars to accept, i.e. .replace(/[^0-9-\.]+/g, "") – tonycoupland Nov 27 '13 at 13:28
  • 6
    Also keep in mind that some accounting apps wrap numbers in parentheses to denote negative values. e.g.: ($5.00) = -$5.00 – Dave L Nov 06 '15 at 20:20
  • 1
    I know I may be several years late on replying here, but you also need to be careful if "currency = 0." you will get a javascript error saying that currency.replace is not a function. I just added a simple check if currency = 0 to avoid this. – Allen Sep 19 '16 at 20:24
  • 1
    `.` does not need to be escaped within a character class; the regex can simply be `/[^0-9.]+/` –  Jul 17 '17 at 16:49
  • 2
    this doesn't work if your currency is in brazilian, because their use ',' separator. – Quethzel Diaz Mar 06 '19 at 17:45
  • Good and simple answer. – Hasan Badshah Dec 22 '22 at 23:48
28

accounting.js is the way to go. I used it at a project and had very good experience using it.

accounting.formatMoney(4999.99, "€", 2, ".", ","); // €4.999,99
accounting.unformat("€ 1.000.000,00", ","); // 1000000

You can find it at GitHub

andrewtweber
  • 24,520
  • 22
  • 88
  • 110
Thomas Kremmel
  • 14,575
  • 26
  • 108
  • 177
  • 18
    Update: That library has 71 open issues and hasn't been edited in 5 months, so I'm not trusting it. https://github.com/openexchangerates/accounting.js/issues – Ryan Aug 09 '17 at 21:19
  • 1
    Update: Now, 100 open issues and 32 pull requests. – Legendary Emoji Mar 31 '22 at 20:25
24

Use a regex to remove the formating (dollar and comma), and use parseFloat to convert the string to a floating point number.`

var currency = "$1,100.00";
currency.replace(/[$,]+/g,"");
var result = parseFloat(currency) + .05;
Jamie
  • 2,104
  • 1
  • 15
  • 9
  • 10
    Worth noting you shouldn't be using float for any non 'Toy' applications when your adding currency. You will end up with **not** exact totals. – Ally Jul 19 '12 at 16:24
  • 7
    You will be surprised and unhappy when parseFloat("151.20" * 100) gives you 15119.999999999998 but parseFloat("151.40" * 100) gives you 15140. Do not ever use parseFloat for money. Use specific libraries for dealing with money, such as accounting.js or any of the other ones suggested here. – bambery May 22 '15 at 18:35
  • 6
    what is `+ .05` for? – sg552 Sep 02 '20 at 13:31
20

I know this is an old question but wanted to give an additional option.

The jQuery Globalize gives the ability to parse a culture specific format to a float.

https://github.com/jquery/globalize

Given a string "$13,042.00", and Globalize set to en-US:

Globalize.culture("en-US");

You can parse the float value out like so:

var result = Globalize.parseFloat(Globalize.format("$13,042.00", "c"));

This will give you:

13042.00

And allows you to work with other cultures.

Andy Stabler
  • 1,309
  • 1
  • 15
  • 19
Phill
  • 18,398
  • 7
  • 62
  • 102
18

I know this is an old question, but CMS's answer seems to have one tiny little flaw: it only works if currency format uses "." as decimal separator. For example, if you need to work with russian rubles, the string will look like this: "1 000,00 rub."

My solution is far less elegant than CMS's, but it should do the trick.

var currency = "1 000,00 rub."; //it works for US-style currency strings as well
var cur_re = /\D*(\d+|\d.*?\d)(?:\D+(\d{2}))?\D*$/;
var parts = cur_re.exec(currency);
var number = parseFloat(parts[1].replace(/\D/,'')+'.'+(parts[2]?parts[2]:'00'));
console.log(number.toFixed(2));

Assumptions:

  • currency value uses decimal notation
  • there are no digits in the string that are not a part of the currency value
  • currency value contains either 0 or 2 digits in its fractional part *

The regexp can even handle something like "1,999 dollars and 99 cents", though it isn't an intended feature and it should not be relied upon.

Hope this will help someone.

mplungjan
  • 169,008
  • 28
  • 173
  • 236
Vindicar
  • 354
  • 2
  • 9
  • 1
    Thank you. Best answer. Simple and mighty. I would use it with (\D*)(\d.*?\d)(?:\D+(\d{2}|-))?(\D*)$ to get the currency and - for cents. So you can parse strings like 1.000,- € too. The currency will be in parts[1] or part[4] and part[3] includes cents as number or -. Than you can normalize the string like you want. – CyberAleks Dec 13 '16 at 09:31
  • This is very bad and dangerous, this multiplies numbers less than 10 by 100. I foolishly used it before testing all numbers with it :( – sheavens May 31 '17 at 11:46
  • @sheavens thanks for reporting it. Apologies for fixing it so late, but the new version actually works for those sums too. – Vindicar Sep 23 '18 at 10:51
13

This example run ok

var currency = "$1,123,456.00";
var number = Number(currency.replace(/[^0-9\.]+/g,""));
console.log(number);
Brian Burns
  • 20,575
  • 8
  • 83
  • 77
Tony Nguyen
  • 413
  • 5
  • 11
12

For anyone looking for a solution in 2021 you can use Currency.js.

After much research this was the most reliable method I found for production, I didn't have any issues so far. In addition it's very active on Github.

currency(123);      // 123.00
currency(1.23);     // 1.23
currency("1.23")    // 1.23
currency("$12.30")  // 12.30

var value = currency("123.45");
currency(value);    // 123.45

typescript

import currency from "currency.js";

currency("$12.30").value;    // 12.30
xinthose
  • 3,213
  • 3
  • 40
  • 59
Diego Fortes
  • 8,830
  • 3
  • 32
  • 42
  • This is great recommendation. This library solves some basic problems of JS like doing 2.51 + .01; (which returns 2.5199999999999996) and has a basic formatter for number=>currency string – El Gucs Feb 23 '23 at 04:29
6

This is my function. Works with all currencies..

function toFloat(num) {
    dotPos = num.indexOf('.');
    commaPos = num.indexOf(',');

    if (dotPos < 0)
        dotPos = 0;

    if (commaPos < 0)
        commaPos = 0;

    if ((dotPos > commaPos) && dotPos)
        sep = dotPos;
    else {
        if ((commaPos > dotPos) && commaPos)
            sep = commaPos;
        else
            sep = false;
    }

    if (sep == false)
        return parseFloat(num.replace(/[^\d]/g, ""));

    return parseFloat(
        num.substr(0, sep).replace(/[^\d]/g, "") + '.' + 
        num.substr(sep+1, num.length).replace(/[^0-9]/, "")
    );

}

Usage : toFloat("$1,100.00") or toFloat("1,100.00$")

Nahydrin
  • 13,197
  • 12
  • 59
  • 101
bycoder
  • 61
  • 1
  • 3
6

// "10.000.500,61 TL" price_to_number => 10000500.61

// "10000500.62" number_to_price => 10.000.500,62

JS FIDDLE: https://jsfiddle.net/Limitlessisa/oxhgd32c/

var price="10.000.500,61 TL";
document.getElementById("demo1").innerHTML = price_to_number(price);

var numberPrice="10000500.62";
document.getElementById("demo2").innerHTML = number_to_price(numberPrice);

function price_to_number(v){
    if(!v){return 0;}
    v=v.split('.').join('');
    v=v.split(',').join('.');
    return Number(v.replace(/[^0-9.]/g, ""));
}

function number_to_price(v){
    if(v==0){return '0,00';}
    v=parseFloat(v);
    v=v.toFixed(2).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
    v=v.split('.').join('*').split(',').join('.').split('*').join(',');
    return v;
}
Limitless isa
  • 3,689
  • 36
  • 28
5

You can try this

var str = "$1,112.12";
str = str.replace(",", "");
str = str.replace("$", "");
console.log(parseFloat(str));
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Ólafur Waage
  • 68,817
  • 22
  • 142
  • 198
  • 3
    This fails with something like "$1,000,000.00" -> 1000 - need to use regexp to replace all occurrences in a string – Brian Burns Aug 28 '20 at 19:34
4
let thousands_seps = '.';
let decimal_sep = ',';

let sanitizeValue = "R$ 2.530,55".replace(thousands_seps,'')
                         .replace(decimal_sep,'.')
                         .replace(/[^0-9.-]+/, '');

// Converting to float
// Result 2530.55
let stringToFloat = parseFloat(sanitizeValue);


// Formatting for currency: "R$ 2.530,55"
// BRL in this case
let floatTocurrency = Number(stringToFloat).toLocaleString('pt-BR', {style: 'currency', currency: 'BRL'});

// Output
console.log(stringToFloat, floatTocurrency);
3

I know you've found a solution to your question, I just wanted to recommend that maybe you look at the following more extensive jQuery plugin for International Number Formats:

International Number Formatter

IEnumerator
  • 2,960
  • 5
  • 31
  • 33
3

How about simply

Number(currency.replace(/[^0-9-]+/g,""))/100;

Works with all currencies and locales. replaces all non-numeric chars (you can have €50.000,00 or $50,000.00) input must have 2 decimal places

  • 2
    `var currency = "1000"; console.log(Number(currency.replace(/[^0-9-]+/g,""))/100;)` output is 10. This just gave your customers a 99% discount. same with `currency = "1,000". – Frank Forte Apr 13 '22 at 21:44
3

For currencies that use the ',' separator mentioned by Quethzel Diaz

Currency is in Brazilian.

var currency_br = "R$ 1.343,45";
currency_br = currency_br.replace('.', "").replace(',', '.');
var number_formated = Number(currency_br.replace(/[^0-9.-]+/g,""));
2
jQuery.preferCulture("en-IN");
var price = jQuery.format(39.00, "c");

output is: Rs. 39.00

use jquery.glob.js,
    jQuery.glob.all.js
TLama
  • 75,147
  • 17
  • 214
  • 392
2

Here's a simple function -

function getNumberFromCurrency(currency) {
  return Number(currency.replace(/[$,]/g,''))
}

console.log(getNumberFromCurrency('$1,000,000.99')) // 1000000.99
Brian Burns
  • 20,575
  • 8
  • 83
  • 77
2

Such a headache and so less consideration to other cultures for nothing...

here it is folks:

let floatPrice = parseFloat(price.replace(/(,|\.)([0-9]{3})/g,'$2').replace(/(,|\.)/,'.'));

as simple as that.

F. Müller
  • 3,969
  • 8
  • 38
  • 49
1
var parseCurrency = function (e) {
    if (typeof (e) === 'number') return e;
    if (typeof (e) === 'string') {
        var str = e.trim();
        var value = Number(e.replace(/[^0-9.-]+/g, ""));
        return str.startsWith('(') && str.endsWith(')') ? -value: value;
    }

    return e;
} 
Vladislav Kostenko
  • 1,155
  • 11
  • 18
1

This worked for me and covers most edge cases :)

function toFloat(num) {
  const cleanStr = String(num).replace(/[^0-9.,]/g, '');
  let dotPos = cleanStr.indexOf('.');
  let commaPos = cleanStr.indexOf(',');

  if (dotPos < 0) dotPos = 0;

  if (commaPos < 0) commaPos = 0;

  const dotSplit = cleanStr.split('.');
  const commaSplit = cleanStr.split(',');

  const isDecimalDot = dotPos
    && (
      (commaPos && dotPos > commaPos)
      || (!commaPos && dotSplit[dotSplit.length - 1].length === 2)
    );

  const isDecimalComma = commaPos
    && (
      (dotPos && dotPos < commaPos)
      || (!dotPos && commaSplit[commaSplit.length - 1].length === 2)
    );

  let integerPart = cleanStr;
  let decimalPart = '0';
  if (isDecimalComma) {
    integerPart = commaSplit[0];
    decimalPart = commaSplit[1];
  }
  if (isDecimalDot) {
    integerPart = dotSplit[0];
    decimalPart = dotSplit[1];
  }

  return parseFloat(
    `${integerPart.replace(/[^0-9]/g, '')}.${decimalPart.replace(/[^0-9]/g, '')}`,
  );
}

toFloat('USD 1,500.00'); // 1500
toFloat('USD 1,500'); // 1500
toFloat('USD 500.00'); // 500
toFloat('USD 500'); // 500

toFloat('EUR 1.500,00'); // 1500
toFloat('EUR 1.500'); // 1500
toFloat('EUR 500,00'); // 500
toFloat('EUR 500'); // 500
Simo
  • 464
  • 3
  • 16
0
    $ 150.00
    Fr. 150.00
    € 689.00

I have tested for above three currency symbols .You can do it for others also.

    var price = Fr. 150.00;
    var priceFloat = price.replace(/[^\d\.]/g, '');

Above regular expression will remove everything that is not a digit or a period.So You can get the string without currency symbol but in case of " Fr. 150.00 " if you console for output then you will get price as

    console.log('priceFloat : '+priceFloat);

    output will be like  priceFloat : .150.00

which is wrong so you check the index of "." then split that and get the proper result.

    if (priceFloat.indexOf('.') == 0) {
            priceFloat = parseFloat(priceFloat.split('.')[1]);
    }else{
            priceFloat = parseFloat(priceFloat);
    }
Jyotiranjan
  • 683
  • 8
  • 20
0
function NumberConvertToDecimal (number) {
    if (number == 0) {
       return '0.00'; 
    }
    number = parseFloat(number);
    number = number.toFixed(2).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1");
    number = number.split('.').join('*').split('*').join('.');
    return number;
}
0

This function should work whichever the locale and currency settings :

function getNumPrice(price, decimalpoint) {
    var p = price.split(decimalpoint);
    for (var i=0;i<p.length;i++) p[i] = p[i].replace(/\D/g,'');
    return p.join('.');
}

This assumes you know the decimal point character (in my case the locale is set from PHP, so I get it with <?php echo cms_function_to_get_decimal_point(); ?>).

Skippy le Grand Gourou
  • 6,976
  • 4
  • 60
  • 76
0

You should be able to handle this using vanilla JS. The Internationalization API is part of JS core: ECMAScript Internationalization API https://www.w3.org/International/wiki/JavaScriptInternationalization

This answer worked for me: How to format numbers as currency strings

ben.hamelin
  • 181
  • 1
  • 4
0

I think this should work:

function formatPriceFromString(price) {
  price = price.replace(/[^\d\.\,]+/g, '')
  // WHEN PRICE FORMAT 1.000,00
  if (/\.[^\,\.]+\,/g.test(price))
    price = price.replace(/\./g, '').replace(/\,/, '.')
  // WHEN PRICE FORMAT 1,000.00
  else if (/\,[^\,\.]+\./g.test(price))
    price = price.replace(/\,/g, '')
  // WHEN PRICE FORMAT 100,00 OR 100.00
  else
    price = price.replace(/\,/g, '.')

  return Number(price)
}

console.log(formatPriceFromString('$1,100.00'))
console.log(formatPriceFromString('$1,100,000.00'))
console.log(formatPriceFromString('$1,100.00'))
console.log(formatPriceFromString('$1.100,00'))
console.log(formatPriceFromString('$1.100.000,00'))
console.log(formatPriceFromString('$1 100 000,00'))
console.log(formatPriceFromString('$1 100 000.00'))
console.log(formatPriceFromString('134, 99 PLN'))
 LOG  1100
 LOG  1100000
 LOG  1100
 LOG  1100
 LOG  1100000
 LOG  1100000
 LOG  1100000
 LOG  134.99
Kesha Antonov
  • 349
  • 5
  • 14
0

use this robot generated answer

function toFloat(num) {
  const cleanStr = String(num).replace(/[^0-9.,]/g, '');
  const [integerPart, decimalPart] = cleanStr
    .split(/[.,]/)
    .map(part => part.replace(/[^0-9]/g, ''));

  return parseFloat(`${integerPart}.${decimalPart}`);
}