Separador de miles de JavaScript / formato de cadena [duplicado]


96

¿Hay alguna función en Javascript para formatear números y cadenas?

Estoy buscando una forma de separador de miles para cadenas o números ... (como String.Format en c #)



Creo que encontrará lo que necesita allí :) stackoverflow.com/questions/610406/…
Jad

How to print a number with commas as thousands separators in JavaScript: stackoverflow.com/questions/2901102/…
Adrien Be

Respuestas:


160

Actualización (7 años después)

La referencia citada en la respuesta original a continuación era incorrecta. No es una función integrada para esto, que es exactamente lo que Kaiser sugiere a continuación:toLocaleString

Entonces puedes hacer:

(1234567.89).toLocaleString('en')              // for numeric input
parseFloat("1234567.89").toLocaleString('en')  // for string input

La función implementada a continuación también funciona, pero simplemente no es necesaria.

(Pensé que tal vez tendría suerte y descubriría que era necesario en 2010, pero no. Según esta referencia más confiable , toLocaleString ha sido parte del estándar desde ECMAScript 3rd Edition [1999], lo que creo que significa que habría sido compatible desde IE 5.5.)


Respuesta original

Según esta referencia, no hay una función incorporada para agregar comas a un número. Pero esa página incluye un ejemplo de cómo codificarlo usted mismo:

function addCommas(nStr) {
    nStr += '';
    var x = nStr.split('.');
    var x1 = x[0];
    var x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
            x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
}

Editar: para ir al revés (convertir la cadena con comas en un número), puede hacer algo como esto:

parseFloat("1,234,567.89".replace(/,/g,''))

Realmente, realmente lo aprecio // Pero, ¿cómo puedo convertir esa cadena (con comas) en un número?
LostLord

esta función se interrumpe para números superiores a 100.000
DevZer0

1
@ DevZer0 no, no lo hace
Tallboy

funciona con javascript puro + una sola expresión regular reemplace stackoverflow.com/a/44324879/681830
Val

4
uso (1234567).toLocaleString().replace(/,/g," ",)para espacios entre miles
Fanky

122

Si se trata de localizar separadores de miles, delimitadores y separadores decimales, elija lo siguiente:

// --> numObj.toLocaleString( [locales [, options] ] )
parseInt( number ).toLocaleString();

Hay varias opciones que puede usar (e incluso configuraciones regionales con alternativas):

number = 123456.7089;

result  = parseInt( number ).toLocaleString() + "<br>";
result += number.toLocaleString( 'de-DE' ) + "<br>";
result += number.toLocaleString( 'ar-EG' ) + "<br>";
result += number.toLocaleString( 'ja-JP', { 
  style           : 'currency',
  currency        : 'JPY',
  currencyDisplay : 'symbol',
  useGrouping     : true
} ) + "<br>";
result += number.toLocaleString( [ 'jav', 'en' ], { 
  localeMatcher            : 'lookup',
  style                    : 'decimal',
  minimumIntegerDigits     : 2,
  minimumFractionDigits    : 2,
  maximumFractionDigits    : 3,
  minimumSignificantDigits : 2,
  maximumSignificantDigits : 3
} ) + "<br>";

var el = document.getElementById( 'result' );
el.innerHTML = result;
<div id="result"></div>

Detalles en la página de información de MDN .

Editar: Commentor @I like Serena agrega lo siguiente:

Para admitir navegadores con una configuración regional que no esté en inglés donde todavía queremos formato en inglés, use value.toLocaleString('en'). También funciona para coma flotante.


Esto no cubre los números flotantes ... puede cambiar parseInt a parseFloat, pero si yourInt = "100,12" (coma como separador decimal) esto fallará. Esto se puede arreglar con un reemplazo (",", ".") .. pero fallará nuevamente con "1.000,12". Entonces ... DEBES reinventar la rueda a veces. stackoverflow.com/a/2901298/1028304
neiker

No funciona bien. El uso de comas en nuestro espacio local es común para el separador de miles.
Josef Sábl

1
Esto sería más apropiado:Number(yourNumberOrString).toLocaleString()
Jonathan

2
Para admitir navegadores con una configuración regional que no esté en inglés donde todavía queremos formato en inglés, use value.toLocaleString('en'). También funciona para coma flotante.
Klaas van Aarsen

1
@ Serhiog.Lazin ¿Qué es exactamente lo que no funciona en Safari (y en qué sistema operativo y en qué versión)?
Kaiser

35

Se actualizó utilizando el soporte de búsqueda retrospectiva de acuerdo con los cambios de ECMAScript2018.
Para compatibilidad con versiones anteriores, desplácese hacia abajo para ver la solución original.

Se puede utilizar una expresión regular, especialmente útil para tratar con números grandes almacenados como cadenas.

const format = num => 
    String(num).replace(/(?<!\..*)(\d)(?=(?:\d{3})+(?:\.|$))/g, '$1,')

;[
    format(100),                           // "100"
    format(1000),                          // "1,000"
    format(1e10),                          // "10,000,000,000"  
    format(1000.001001),                   // "1,000.001001"
    format('100000000000000.001001001001') // "100,000,000,000,000.001001001001
]
    .forEach(n => console.log(n))

»Explicación detallada de expresiones regulares (regex101.com) diagrama de flujo


Es posible que esta respuesta original no sea necesaria, pero se puede utilizar para compatibilidad con versiones anteriores.

Al intentar manejar esto con una sola expresión regular (sin devolución de llamada), mi capacidad actual me falla por falta de una búsqueda negativa en Javascript ... sin embargo, aquí hay otra alternativa concisa que funciona en la mayoría de los casos generales: teniendo en cuenta cualquier punto decimal ignorando coincidencias donde el índice de la coincidencia aparece después del índice de un período.

const format = num => {
    const n = String(num),
          p = n.indexOf('.')
    return n.replace(
        /\d(?=(?:\d{3})+(?:\.|$))/g,
        (m, i) => p < 0 || i < p ? `${m},` : m
    )
}

;[
    format(100),                           // "100"
    format(1000),                          // "1,000"
    format(1e10),                          // "10,000,000,000"  
    format(1000.001001),                   // "1,000.001001"
    format('100000000000000.001001001001') // "100,000,000,000,000.001001001001
]
    .forEach(n => console.log(n))

»Explicación detallada de expresiones regulares (regex101.com)

diagrama de flujo


¿Se ha creado este diagrama de sintaxis en regex101.com?
Gerold Broser

¿Qué pasa con los números con decimales?
Emiliano

Recibo "Expresión regular no válida: nombre de especificador de grupo no válido". En React Native 0.59 haciendo esto, pero eso realmente no debería afectar la expresión regular.
Joshua Pinter

@JoshuaPinter Será el uso de mirar atrás, que en el momento de escribir este artículo aún no se admite en todas las plataformas. Supongo que te refieres específicamente a iOS, ya que Safari todavía me falla. Puede que sea mejor quedarse con la versión compatible con versiones anteriores por ahora. Solo estaba tratando de preparar mi respuesta para el futuro. caniuse.com/#search=lookbehind
Emisario

1
@Emisario Gracias por el dato. Sí, está en React Native 0.59 / Android, que usa una versión relativamente anterior de JavaScriptCore (JSC). Volveré a intentarlo después de actualizar a React Native 0.60+, que incluye una actualización del JSC.
Joshua Pinter

10

Hay un buen complemento de número de jQuery: https://github.com/teamdf/jquery-number

Le permite cambiar cualquier número en el formato que desee, con opciones para dígitos decimales y caracteres separadores para decimal y mil:

$.number(12345.4556, 2);          // -> 12,345.46
$.number(12345.4556, 3, ',', ' ') // -> 12 345,456

Puede usarlo directamente dentro de los campos de entrada, lo cual es mejor, usando las mismas opciones que las anteriores:

$("input").number(true, 2);

O puede aplicar a un conjunto completo de elementos DOM usando el selector:

$('span.number').number(true, 2);

la mejor solución en mi humilde opinión
Michal

No lo creo, agregar un nuevo requisito de archivo con casi 800 líneas, es como matar una hormiga con una granada
Emiliano

6

Yo uso esto:

function numberWithCommas(number) {
    return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

fuente: enlace


'123452343267.0505'.replace(/\B(?=(\d{3})+(?!\d))/g, ","); "123,452,343,267.0,505"- observe la última coma después del punto decimal.
hippietrail

5
// thousand separates a digit-only string using commas
// by element:  onkeyup = "ThousandSeparate(this)"
// by ID:       onkeyup = "ThousandSeparate('txt1','lbl1')"
function ThousandSeparate()
{
    if (arguments.length == 1)
    {
        var V = arguments[0].value;
        V = V.replace(/,/g,'');
        var R = new RegExp('(-?[0-9]+)([0-9]{3})'); 
        while(R.test(V))
        {
            V = V.replace(R, '$1,$2');
        }
        arguments[0].value = V;
    }
    else  if ( arguments.length == 2)
    {
        var V = document.getElementById(arguments[0]).value;
        var R = new RegExp('(-?[0-9]+)([0-9]{3})'); 
        while(R.test(V))
        {
            V = V.replace(R, '$1,$2');
        }
        document.getElementById(arguments[1]).innerHTML = V;
    }
    else return false;
}   


3

Puede utilizar javascript. a continuación se muestra el código, solo será acceptnumérico y unodot

aquí está el javascript

<script >

            function FormatCurrency(ctrl) {
                //Check if arrow keys are pressed - we want to allow navigation around textbox using arrow keys
                if (event.keyCode == 37 || event.keyCode == 38 || event.keyCode == 39 || event.keyCode == 40) {
                    return;
                }

                var val = ctrl.value;

                val = val.replace(/,/g, "")
                ctrl.value = "";
                val += '';
                x = val.split('.');
                x1 = x[0];
                x2 = x.length > 1 ? '.' + x[1] : '';

                var rgx = /(\d+)(\d{3})/;

                while (rgx.test(x1)) {
                    x1 = x1.replace(rgx, '$1' + ',' + '$2');
                }

                ctrl.value = x1 + x2;
            }

            function CheckNumeric() {
                return event.keyCode >= 48 && event.keyCode <= 57 || event.keyCode == 46;
            }

  </script>

HTML

<input type="text" onkeypress="return CheckNumeric()" onkeyup="FormatCurrency(this)" />

DEMO JSFIDDLE



2
number = 123456.7089;
result = parseInt( number ).toLocaleString() + "<br>";
result = number.toLocaleString( 'pt-BR' ) + "<br>";

var el = document.getElementById( 'result' );
el.innerHTML = result;
<div id="result"></div>

6
¿Puede agregar una descripción también para que el operador y otras personas puedan entender cómo este código realmente resuelve el problema? Gracias
Punit Gajjar

pruebe con un nomber entre 1000 y 9999
Emiliano

1

Todo lo que necesitas hacer es realmente esto :

123000.9123.toLocaleString()
//result will be "123,000.912"

Desafortunadamente, depende de tu plataforma. Algunos tienen un toLocaleString()que no agrega las comas o carece de otras características en el estándar. Es fácil verificar la toLocaleStringpresencia pero no verificar su cumplimiento.
hippietrail

pruebe con un número entre 1000 y 9999
Emiliano

0

Combinación de soluciones para reaccionar

  let converter = Intl.NumberFormat();
  let salary =  monthlySalary.replace(/,/g,'')
  console.log(converter.format(salary))

  this.setState({
    monthlySalary: converter.format(salary)
  })
}

handleOnChangeMonthlySalary(1000)```

0

Puede utilizar ngx-format-field. Es una directiva para formatear el valor de entrada que aparecerá en la vista. No manipulará el valor de entrada que se guardará en el backend. ¡Ver enlace aquí !

Ejemplo:

component.html:

<input type="text" formControlName="currency" [appFormatFields]="CURRENCY"
(change)="onChangeCurrency()">

component.ts

onChangeCurrency() {
this.currency.patchValue(this.currency.value);
}

Para ver la demostración: ¡ aquí !


0

Puede utilizar la siguiente función:

function format(number, decimals = 2, decimalSeparator = '.', thousandsSeparator = ',') {
  const roundedNumber = number.toFixed(decimals);
  let integerPart = '',
    fractionalPart = '';
  if (decimals == 0) {
    integerPart = roundedNumber;
    decimalSeparator = '';
  } else {
    let numberParts = roundedNumber.split('.');
    integerPart = numberParts[0];
    fractionalPart = numberParts[1];
  }
  integerPart = integerPart.replace(/(\d)(?=(\d{3})+(?!\d))/g, `$1${thousandsSeparator}`);
  return `${integerPart}${decimalSeparator}${fractionalPart}`;
}

// Use Example

let min = 1556454.0001;
let max = 15556982.9999;

console.time('number format');
for (let i = 0; i < 15; i++) {
  let randomNumber = Math.random() * (max - min) + min;
  let formated = format(randomNumber, 4, ',', '.'); // formated number

  console.log('number: ', randomNumber, '; formated: ', formated);
}
console.timeEnd('number format');


No lo hagas tan confuso. solo use toLocaleString (). Más información en developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Sajad Saderi

@sajadsaderi También uso toLocaleString () friend, pero esta función no me da mucha flexibilidad, por lo que no tengo que lidiar con abreviaturas regionales y alguien más podría usarla ya que la definición de esta función es idéntica a number_format () función de php.
jin_maxtor

-1

No me gustó ninguna de las respuestas aquí, así que creé una función que funcionó para mí. Solo quiero compartir en caso de que alguien más lo encuentre útil.

function getFormattedCurrency(num) {
    num = num.toFixed(2)
    var cents = (num - Math.floor(num)).toFixed(2);
    return Math.floor(num).toLocaleString() + '.' + cents.split('.')[1];
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.