¿Cómo convertir una cadena de moneda a un doble con jQuery o Javascript?

237

Tengo un cuadro de texto que tendrá una cadena de moneda y luego tendré que convertir esa cadena a un doble para realizar algunas operaciones.

"$1,100.00"1100.00

Esto debe ocurrir en todo el lado del cliente. No tengo más remedio que dejar la cadena de moneda como una cadena de moneda como entrada, pero necesito convertirla / convertirla en un doble para permitir algunas operaciones matemáticas.

Bobby Borszich
fuente

Respuestas:

480

Eliminar todos los puntos / dígitos que no sean:

var currency = "-$4,400.50";
var number = Number(currency.replace(/[^0-9.-]+/g,""));
CMS
fuente
44
Parece que esto solo funciona donde hay un .00final. De lo contrario, representaciones válidas de moneda como "$ 1100" y "$ 1100". se reducirá en dos órdenes de magnitud.
Brian M. Hunt
19
Tenga en cuenta que esto depende de la configuración regional, ya que otras configuraciones regionales usan ',' para decimales (por ejemplo, 1.100,00 €). Algunas otras configuraciones regionales incluso usan un número estándar diferente de dígitos por grupo (como 3 decimales).
smola
8
Para manejar números negativos en la cadena, agregué un '-' a la lista de caracteres para aceptar, es decir .replace (/ [^ 0-9 - \.] + / G, "")
tonycoupland
44
También tenga en cuenta que algunas aplicaciones de contabilidad envuelven los números entre paréntesis para denotar valores negativos. por ejemplo: ($ 5.00) = - $ 5.00
Dave L
1
Sé que puedo tardar varios años en responder aquí, pero también debe tener cuidado si "moneda = 0". obtendrá un error de javascript que dice que currency.replace no es una función. Acabo de agregar un simple cheque si moneda = 0 para evitar esto.
Allen
23

contabilidad.js es el camino a seguir. Lo usé en un proyecto y tuve muy buena experiencia usándolo.

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

Lo puedes encontrar en GitHub

Thomas Kremmel
fuente
66
Actualización: esa biblioteca tiene 71 problemas abiertos y no se ha editado en 5 meses, por lo que no confío en ella. github.com/openexchangerates/accounting.js/issues
Ryan
20

Use una expresión regular para eliminar el formato (dólar y coma), y use parseFloat para convertir la cadena en un número de coma flotante.

var currency = "$1,100.00";
currency.replace(/[$,]+/g,"");
var result = parseFloat(currency) + .05;
Jamie
fuente
8
Vale la pena señalar que no debería usar flotador para ninguna aplicación que no sea 'Toy' cuando agregue moneda. Terminarás con totales no exactos.
Ally
66
Se sorprenderá e infeliz cuando parseFloat ("151.20" * 100) le dé 15119.999999999998 pero parseFloat ("151.40" * 100) le dé 15140. Nunca use parseFloat por dinero. Utilice bibliotecas específicas para tratar con dinero, como Accounting.js o cualquiera de los otros sugeridos aquí.
bambery
15

Sé que esta es una vieja pregunta, pero quería dar una opción adicional.

JQuery Globalize brinda la capacidad de analizar un formato específico de cultura en un flotante.

https://github.com/jquery/globalize

Dada una cadena "$ 13,042.00", y Globalize configurado en en-US:

Globalize.culture("en-US");

Puede analizar el valor flotante de la siguiente manera:

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

Esto te dará:

13042.00

Y te permite trabajar con otras culturas.

Phill
fuente
10

Sé que esta es una vieja pregunta, pero la respuesta de CMS parece tener una pequeña falla: solo funciona si el formato de moneda usa "". como separador decimal Por ejemplo, si necesita trabajar con rublos rusos, la cadena se verá así: "1 000,00 rub".

Mi solución es mucho menos elegante que la de los CMS, pero debería funcionar.

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

Suposiciones

  • el valor de la moneda usa notación decimal
  • no hay dígitos en la cadena que no sean parte del valor de la moneda
  • El valor de la moneda contiene 0 o 2 dígitos en su parte fraccional *

La expresión regular puede incluso manejar algo como "1,999 dólares y 99 centavos", aunque no es una característica prevista y no se debe confiar en ella.

Espero que esto ayude a alguien.

Vindicar
fuente
Gracias. La mejor respuesta. Simple y poderoso. Lo usaría con (\ D *) (\ d. *? \ D) (?: \ D + (\ d {2} | -))? (\ D *) $ para obtener la moneda y - por centavos. Para que pueda analizar cadenas como 1.000, - € también. La moneda estará en partes [1] o parte [4] y la parte [3] incluye centavos como número o -. Entonces puedes normalizar la cadena como quieras.
CyberAleks
Esto es muy malo y peligroso, esto multiplica números menos de 10 por 100. Lo utilicé tontamente antes de probar todos los números con él :(
sheavens
@sheavens gracias por informarlo. Disculpas por arreglarlo tan tarde, pero la nueva versión también funciona para esas sumas.
Vindicar
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;
}
Isa ilimitado
fuente
3

Sé que has encontrado una solución a tu pregunta, solo quería recomendarte que quizás mires el siguiente plugin jQuery más extenso para formatos de números internacionales:

Formateador internacional de números

IEnumerator
fuente
3

Esta es mi funcion. Funciona con todas las monedas.

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

}

Uso: toFloat("$1,100.00")otoFloat("1,100.00$")

codificador
fuente
3

Puedes probar esto

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

Ólafur Waage
fuente
2
jQuery.preferCulture("en-IN");
var price = jQuery.format(39.00, "c");

la salida es: Rs. 39,00

use jquery.glob.js,
    jQuery.glob.all.js
Rajesh Kumar Maurya
fuente
0
    $ 150.00
    Fr. 150.00
     689.00

He probado más de tres símbolos de moneda. También puedes hacerlo para otros.

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

La expresión regular anterior eliminará todo lo que no sea un dígito o un punto. Por lo tanto, puede obtener la cadena sin el símbolo de moneda, pero en el caso de "Fr. 150.00" si consuela la salida, obtendrá el precio como

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

    output will be like  priceFloat : .150.00

que está mal, así que verifica el índice de "." luego divídalo y obtenga el resultado adecuado.

    if (priceFloat.indexOf('.') == 0) {
            priceFloat = parseFloat(priceFloat.split('.')[1]);
    }else{
            priceFloat = parseFloat(priceFloat);
    }
Jyotiranjan
fuente
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;
}
Santosh Bharadwaj
fuente
0
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
fuente
0

Esta función debería funcionar independientemente de la configuración regional y de moneda:

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

Esto supone que conoce el carácter del punto decimal (en mi caso, la configuración regional se establece desde PHP, así que lo entiendo <?php echo cms_function_to_get_decimal_point(); ?>).

Skippy le Grand Gourou
fuente
0

Esto funcionó para mí y cubre la mayoría de los casos extremos :)

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
melalj
fuente