Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

1.1K
Visualizações
Regex to separate thousands with comma and keep two decimals

I recently came up with this code while answering another StackOverflow question. Basically, on blur, this code will properly comma separate by thousands and leave the decimal at two digits (like how USD is written [7,745.56]).

I was wondering if there is more concise way of using regex to , separate and cut off excessive decimal places. I recently updated this post with my most recent attempt. Is there a better way of doing this with regex?

Input -> Target Output

7456 -> 7,456
45345 -> 45,345
25.23523534 -> 25.23
3333.239 -> 3,333.23
234.99 -> 234.99
2300.99 -> 2,300.99
23123123123.22 -> 23,123,123,123.22

Current Regex

var result;
var str = []
reg = new RegExp(/(\d*(\d{2}\.)|\d{1,3})/, "gi");
reversed = "9515321312.2323432".split("").reverse().join("")
while (result = reg.exec(reversed)) {
  str.push(result[2] ? result[2] : result[0])
}
console.log(str.join(",").split("").reverse().join("").replace(",.","."))

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

As an alternative to the Regex, you could use the following approach

Number(num.toFixed(2)).toLocaleString('en-US')

or

num.toLocaleString('en-US', {maximumFractionDigits: 2})

You would still have the toFixed(2), but it's quite clean. toFixed(2) though won't floor the number like you want. Same with {maximumFractionDigits: 2} as the second parameter to toLocaleString as well.

var nums = [7456, 45345, 25.23523534, 3333.239, 234.99, 2300.99, 23123123123.22]

for (var num of nums) 
  console.log(num, '->',  Number(num.toFixed(2)).toLocaleString('en-US') )

Flooring the number like you showed is a bit tricky. Doing something like (num * 100 | 0) / 100 does not work. The calculation loses precision (e.g. .99 will become .98 in certain situations). (also |0 wouldn't work with larger numbers but even Math.floor() has the precision problem).

The solution would be to treat the numbers like strings.

function format(num) {
    var num = num.toLocaleString('en-US')
    var end = num.indexOf('.') < 0 ? num.length : num.indexOf('.') + 3
    return num.substring(0, end)
}

var nums = [7456, 45345, 25.23523534, 3333.239, 234.99, 2300.99, 23123123123.22]

for (var num of nums) console.log(num, '->', format(num))

function format(num) {
  var num = num.toLocaleString('en-US')
  var end = num.indexOf('.') < 0 ? num.length : num.indexOf('.') + 3
  return num.substring(0, end)
}

(when changing to another format than 'en-US' pay attention to the . in numbers as some languages use a , as fractal separator)

For Compatibility, according to CanIUse toLocaleString('en-US') is

supported in effectively all browsers (since IE6+, Firefox 2+, Chrome 1+ etc)

over 4 years ago · Santiago Trujillo Relatório

0

If you really insist on doing this purely in regex (and truncate instead of round the fractional digits), the only solution I can think of is to use a replacement function as the second argument to .replace():

('' + num).replace(
  /(\d)(?=(?:\d{3})+(?:\.|$))|(\.\d\d?)\d*$/g, 
  function(m, s1, s2){
    return s2 || (s1 + ',');
  }
);

This makes all your test cases pass:

function format(num){
  return ('' + num).replace(
    /(\d)(?=(?:\d{3})+(?:\.|$))|(\.\d\d?)\d*$/g, 
    function(m, s1, s2){
      return s2 || (s1 + ',');
    }
  );
}


test(7456, "7,456");
test(45345, "45,345");
test(25.23523534, "25.23"); //truncated, not rounded
test(3333.239, "3,333.23"); //truncated, not rounded
test(234.99, "234.99");
test(2300.99, "2,300.99");
test(23123123123.22, "23,123,123,123.22");

function test(num, expected){
  var actual = format(num);
  console.log(num + ' -> ' + expected + ' => ' + actual + ': ' + 
    (actual === expected ? 'passed' : 'failed')
   );
}

over 4 years ago · Santiago Trujillo Relatório

0

Try:

var n = 5812090285.2817481974897;
n = n.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,');
console.log(n);

Outputs:

5,812,090,285.28

Note: .toFixed(2) returns a string. So in order to simplify this further you must add a way to turn n into a string before executing your regex. For example:

n.toString.replace(/(\d)(?=(\d{3})+\.)/g, '$1,');  //ofc with the additional regex

Although you would think it wouldn't matter in javascript, it apparently does in this situation. So I dont know how much 'less' messy it would be to not use.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda