308

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.

2
  • 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. Commented Dec 19, 2022 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. Commented Feb 6, 2023 at 20:52

25 Answers 25

604

Remove all non dot / digits:

var currency = "-$4,400.50"; var number = Number(currency.replace(/[^0-9.-]+/g,"")); 
Sign up to request clarification or add additional context in comments.

8 Comments

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.
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).
To handle negative numbers in the string, I added a '-' to the list of chars to accept, i.e. .replace(/[^0-9-\.]+/g, "")
Also keep in mind that some accounting apps wrap numbers in parentheses to denote negative values. e.g.: ($5.00) = -$5.00
this doesn't work if your currency is in brazilian, because their use ',' separator.
|
29

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

2 Comments

Update: That library has 71 open issues and hasn't been edited in 5 months, so I'm not trusting it. github.com/openexchangerates/accounting.js/issues
Update: Now, 100 open issues and 32 pull requests.
25

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; 

3 Comments

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.
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.
what is + .05 for?
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.

Comments

20

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.

3 Comments

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.
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 thanks for reporting it. Apologies for fixing it so late, but the new version actually works for those sums too.
14

This example run ok

var currency = "$1,123,456.00"; var number = Number(currency.replace(/[^0-9\.]+/g,"")); console.log(number);

Comments

14

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 

1 Comment

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
7

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$")

Comments

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

Comments

6

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

Comments

5

You can try this

var str = "$1,112.12"; str = str.replace(",", ""); str = str.replace("$", ""); console.log(parseFloat(str));

1 Comment

This fails with something like "$1,000,000.00" -> 1000 - need to use regexp to replace all occurrences in a string
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); 

1 Comment

Muito bom, Victor.
4

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 Comments

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".
Once you delete the "/100", it works very nicely. It is intelligent enough that something like '839.47' is properly converted to the number 839.47 without using the '/100'.
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

Comments

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 

Comments

2

Here's a simple function -

function getNumberFromCurrency(currency) { return Number(currency.replace(/[$,]/g,'')) } console.log(getNumberFromCurrency('$1,000,000.99')) // 1000000.99

Comments

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.

2 Comments

this works for more situations than the chosen answer. Thanks
If price is "$15,000.00" this gives NaN
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; } 

Comments

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 

Comments

1

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 

Comments

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

Comments

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

Comments

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

Comments

0
// internationalization: either a comma and dot are thousandths/decimal // respectively or vice versa. consider the rightmost \D character to be // the decimal and remove every other occurrence of \D. don't forget to // note the sign of the value. String.prototype.toFixed = function(precision, trim) { precision = precision ? precision : 2; let value = this.valueOf().replace(/[^0-9.,\-()]/g, ``); const negative = value.replace(/^(-.*|\(.*\))$/g, `-`) === `-` ? `-` : ``; value = Number(negative + value.replace(/[^0-9.,]/g, ``).replace(/,/g, `.`).replace(/\.(?=.*\.)/g, ``)).toFixed(precision); if (!(trim === undefined ? false : Boolean(trim))){ return value; } return value.replace(/(0+(?=\.*$)|\.0+$)/, ``); } const value = `$(1,,,20,00.00.00) USD`; // use-case console.log(value.toFixed(4), value.toFixed(4, true)); // -1200000.0000 -1200000 

Comments

-1

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

1 Comment

The question is about currency string=>number, not number=>currency string

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.