Separador de milhar Javascript / formato de string [duplicado]


96

Existe alguma função em Javascript para formatar números e strings?

Estou procurando uma forma de separador de milhar para string ou números ... (como String.Format In c #)



Acho que você encontrará o que precisa lá :) stackoverflow.com/questions/610406/…
Jad de

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

Respostas:


159

Atualização (7 anos depois)

A referência citada na resposta original abaixo estava errada. Não é construído em uma função para isso, que é exatamente o kaiser sugere a seguir:toLocaleString

Então você pode fazer:

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

A função implementada abaixo também funciona, mas simplesmente não é necessária.

(Achei que talvez tivesse sorte e descobrisse que era necessário em 2010, mas não. De acordo com esta referência mais confiável , toLocaleString faz parte do padrão desde ECMAScript 3ª Edição [1999], o que acredito ser o mesmo. teria sido suportado desde o IE 5.5.)


Resposta Original

De acordo com esta referência, não existe uma função incorporada para adicionar vírgulas a um número. Mas essa página inclui um exemplo de como codificá-lo você mesmo:

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 fazer o contrário (converter string com vírgulas em número), você poderia fazer algo assim:

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

Realmente, Realmente Aprecio isso // Mas como posso converter essa string (com vírgulas) em um número?
LostLord de

esta função quebra para números maiores que 100.000
DevZer0

1
@ DevZer0 não, não faz
Tallboy

funciona com javascript puro + regex único substituir stackoverflow.com/a/44324879/681830
Val

4
usar (1234567).toLocaleString().replace(/,/g," ",)para espaços entre milhares
Fanky

122

Se se trata de localizar separadores de milhares, delimitadores e separadores decimais, vá com o seguinte:

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

Existem várias opções que você pode usar (e até mesmo locais com substitutos):

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>

Detalhes na página de informações do MDN .

Edit: Comentador @I like Serena adiciona o seguinte:

Para suportar navegadores com uma localidade diferente do inglês, onde ainda queremos a formatação em inglês, use value.toLocaleString('en'). Também funciona para ponto flutuante.


Isso não cobre números flutuantes .. você pode alterar parseInt para parseFloat, mas se yourInt = "100,12" (vírgula como separador decimal), isso falhará. Isso pode ser corrigido com um replace (",", ".") .. mas falhará novamente com "1.000,12". Então ... Você DEVE reinventar a roda às vezes. stackoverflow.com/a/2901298/1028304
neiker

Não funciona bem. Usa vírgula enquanto em nosso espaço local é comum para separador de milhares.
Josef Sábl

1
Isso seria mais apropriado:Number(yourNumberOrString).toLocaleString()
Jonathan

2
Para suportar navegadores com uma localidade diferente do inglês, onde ainda queremos a formatação em inglês, use value.toLocaleString('en'). Também funciona para ponto flutuante.
Klaas van Aarsen

1
@ Serhiog.Lazin O que exatamente não funciona no Safari (e em qual sistema operacional e em qual versão)?
Kaiser

34

Atualizado usando o suporte de look-behind de acordo com as alterações ECMAScript2018.
Para compatibilidade com versões anteriores, role mais para baixo para ver a solução original.

Uma expressão regular pode ser usada - notavelmente útil para lidar com grandes números armazenados como strings.

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

»Explicação detalhada do regex (regex101.com) diagrama de fluxo


Esta resposta original pode não ser exigida, mas pode ser usada para compatibilidade com versões anteriores.

Tentando lidar com isso com uma única expressão regular (sem retorno de chamada), minha habilidade atual me falha por falta de um look-behind negativo em Javascript ... nunca menos aqui está outra alternativa concisa que funciona na maioria dos casos gerais - levando em conta qualquer ponto decimal ignorando correspondências em que o índice da correspondência aparece após o índice de um 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))

»Explicação detalhada do regex (regex101.com)

diagrama de fluxo


Este diagrama de sintaxe foi criado em regex101.com?
Gerold Broser,

o que acontece com números com decimais?
Emiliano

Estou recebendo "Expressão regular inválida: nome do especificador de grupo inválido". No React Native 0,59 fazendo isso, mas isso realmente não deve afetar o RegEx.
Joshua Pinter

@JoshuaPinter Será o uso de look-behind que, no momento da escrita, ainda não é suportado em todas as plataformas. Suponho que você esteja se referindo especificamente ao iOS - já que o Safari também falha para mim. Pode ser melhor ficar com a versão compatível por enquanto. Eu estava apenas tentando preparar minha resposta para o futuro. caniuse.com/#search=lookbehind
Emissário

1
@Emissary Obrigado pela dica. Sim, está no React Native 0.59 / Android, que usa uma versão relativamente mais antiga do JavaScriptCore (JSC). Vou tentar novamente depois de atualizar para React Native 0.60+, que inclui uma atualização para o JSC.
Joshua Pinter

10

Há um bom plugin de número jQuery: https://github.com/teamdf/jquery-number

Ele permite que você altere qualquer número no formato que desejar, com opções para dígitos decimais e caracteres separadores para decimal e mil:

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

Você pode usá-lo dentro dos campos de entrada diretamente, o que é melhor, usando as mesmas opções acima:

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

Ou você pode aplicar a todo um conjunto de elementos DOM usando o seletor:

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

melhor solução imho
Michal

Acho que não, adicionando um novo requisito de arquivo com quase 800 linhas, é como matar uma formiga com um granade
Emiliano

6

Eu uso isso:

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

fonte: link


'123452343267.0505'.replace(/\B(?=(\d{3})+(?!\d))/g, ","); "123,452,343,267.0,505"- observe a última vírgula após o ponto 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

Você pode usar javascript. abaixo estão o código, será apenas acceptnumérico e umdot

aqui está o 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
Você também pode adicionar alguma descrição para que op e outras pessoas possam entender como esse código realmente resolve o problema. Obrigado
Punit Gajjar

tente com um nomber entre 1000 e 9999
Emiliano


1

Tudo que você precisa fazer é realmente isto :

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

Infelizmente, depende da sua plataforma. Alguns possuem um toLocaleString()que não adiciona vírgulas ou não possuem outros recursos no padrão. É fácil verificar a toLocaleStringpresença, mas não verificar sua conformidade.
hippietrail,

tente com um número entre 1000 e 9999
Emiliano

0

Combinação de soluções para reagir

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

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

handleOnChangeMonthlySalary(1000)```

0

Você pode usar ngx-format-field. É uma diretiva para formatar o valor de entrada que aparecerá na visualização. Não irá manipular o valor de entrada que será salvo no backend. Veja o link aqui !

Exemplo:

component.html:

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

component.ts

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

Para ver a demonstração: aqui !


0

Você pode usar a seguinte função:

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


Não torne isso tão confuso. apenas use toLocaleString (). Mais informações em developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Sajad Saderi

@sajadsaderi Eu também uso o amigo toLocaleString (), mas esta função não me dá muita flexibilidade, então eu não tenho que lidar com abreviações regionais e outra pessoa poderia usá-la, pois a definição desta função é idêntica a number_format () função do php.
jin_maxtor

-1

Não gostei de nenhuma das respostas aqui, então criei uma função que funcionou para mim. Só quero compartilhar, caso alguém mais considere útil.

function getFormattedCurrency(num) {
    num = num.toFixed(2)
    var cents = (num - Math.floor(num)).toFixed(2);
    return Math.floor(num).toLocaleString() + '.' + cents.split('.')[1];
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.