Jak wydrukować liczbę z przecinkami jako separatorami tysięcy w JavaScript

Próbuję wydrukować liczbę całkowitą w JavaScript z przecinkami jako separatorami tysięcy. Na przykład chcę pokazać liczbę 1234567 jako "1,234,567". Jak miałbym to zrobić?

Oto Jak to robię:

function numberWithCommas(x) {
    x = x.toString();
    var pattern = /(-?\d+)(\d{3})/;
    while (pattern.test(x))
        x = x.replace(pattern, "$1,$2");
    return x;
}

Czy istnieje prostszy lub bardziej elegancki sposób, aby to zrobić? Byłoby miło, gdyby działał również z pływakami, ale nie jest to konieczne. Nie musi być specyficzny dla lokalizacji, aby decydować między kropkami i przecinkami.

30 answers

Użyłem pomysłu z odpowiedzi Kerry, ale uprościłem go, ponieważ szukałem czegoś prostego dla mojego konkretnego celu. Oto co zrobiłem:

const numberWithCommas = (x) => {
  return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
To wszystko, co naprawdę musisz wiedzieć.

@Neils Bom zapytał, jak działa regex. Moje wyjaśnienie jest dość długie. Nie zmieści się w komentarzach i nie wiem gdzie jeszcze to umieścić, więc robię to tutaj. Jeśli ktoś ma jakieś inne sugestie, gdzie to umieścić, proszę dać mi znać.

Regex używa 2 lookahead twierdzenia: dodatnie, aby szukać dowolnego punktu w ciągu znaków, który ma wielokrotność 3 cyfr w rzędzie po nim, i ujemne twierdzenie, aby upewnić się, że punkt ma tylko dokładnie wielokrotność 3 cyfr. Wyrażenie zastępcze umieszcza tam przecinek.

Na przykład, jeśli podasz "123456789.01", twierdzenie pozytywne będzie pasować do każdego miejsca po lewej stronie 7 (ponieważ " 789 "to wielokrotność 3 cyfr," 678 "to wielokrotność 3 cyfr," 567 " itd.). Twierdzenie negatywne sprawdza, że wielokrotność 3 cyfr nie ma żadnych cyfr po nim. "789" ma kropkę po nim, więc jest dokładnie wielokrotnością 3 cyfr, więc przecinek idzie tam. "678" jest wielokrotnością 3 cyfr, ale ma "9" po nim, więc te 3 cyfry są częścią grupy 4, A przecinek nie idzie tam. Podobnie w przypadku "567". "456789" to 6 cyfr, czyli wielokrotność 3, więc przecinek przechodzi przed tym. "345678" jest wielokrotnością 3, ale po nim jest" 9" , więc nie ma przecinka. I tak dalej. "\B " zachowuje regex od umieszczenia przecinka na początku łańcucha.

@neu-rah wspomniał, że ta funkcja dodaje przecinki w niepożądanych miejscach, jeśli po przecinku jest więcej niż 3 cyfry. Jeśli jest to problem, możesz użyć tej funkcji:

const numberWithCommas = (x) => {
  var parts = x.toString().split(".");
  parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  return parts.join(".");
}
 2117
Author: Elias Zamaria,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-21 22:16:57

Dziwię się, że nikt nie wspomniał o numerze.prototyp.toLocaleString . Jest zaimplementowany w JavaScript 1.5 (który został wprowadzony w 1999), więc jest zasadniczo obsługiwany przez główne przeglądarki.

var n = 34523453.345
n.toLocaleString()
"34,523,453.345"

Działa również w Node.js od v0. 12 poprzez włączenie Intl

Jeśli chcesz czegoś innego, cyfra.js może być interesujące.

 1106
Author: uKolka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-06 16:30:32
var number = 1234567890; // Example number to be converted

Mind pamiętaj, że javascript ma maksymalną liczbę całkowitą {[5] } 9007199254740991


ToLocaleString:

number.toLocaleString(); // "1,234,567,890"

// A more complex example: 
var number2 = 1234.56789; // floating point example
number2.toLocaleString(undefined, {maximumFractionDigits:2}) // "1,234.57"


NumberFormat (Safari nieobsługiwane):

var nf = new Intl.NumberFormat();
nf.format(number); // "1,234,567,890"

Z tego co sprawdziłem (przynajmniej Firefox) oba są mniej więcej takie same pod względem wydajności.

 183
Author: vsync,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-19 17:38:48

Proponuję użyć phpjs.org " S number_format()

function number_format(number, decimals, dec_point, thousands_sep) {
    // http://kevin.vanzonneveld.net
    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     bugfix by: Michael White (http://getsprink.com)
    // +     bugfix by: Benjamin Lupton
    // +     bugfix by: Allan Jensen (http://www.winternet.no)
    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +     bugfix by: Howard Yeend
    // +    revised by: Luke Smith (http://lucassmith.name)
    // +     bugfix by: Diogo Resende
    // +     bugfix by: Rival
    // +      input by: Kheang Hok Chin (http://www.distantia.ca/)
    // +   improved by: davook
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Jay Klehr
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Amir Habibi (http://www.residence-mixte.com/)
    // +     bugfix by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +   improved by: Drew Noakes
    // *     example 1: number_format(1234.56);
    // *     returns 1: '1,235'
    // *     example 2: number_format(1234.56, 2, ',', ' ');
    // *     returns 2: '1 234,56'
    // *     example 3: number_format(1234.5678, 2, '.', '');
    // *     returns 3: '1234.57'
    // *     example 4: number_format(67, 2, ',', '.');
    // *     returns 4: '67,00'
    // *     example 5: number_format(1000);
    // *     returns 5: '1,000'
    // *     example 6: number_format(67.311, 2);
    // *     returns 6: '67.31'
    // *     example 7: number_format(1000.55, 1);
    // *     returns 7: '1,000.6'
    // *     example 8: number_format(67000, 5, ',', '.');
    // *     returns 8: '67.000,00000'
    // *     example 9: number_format(0.9, 0);
    // *     returns 9: '1'
    // *    example 10: number_format('1.20', 2);
    // *    returns 10: '1.20'
    // *    example 11: number_format('1.20', 4);
    // *    returns 11: '1.2000'
    // *    example 12: number_format('1.2000', 3);
    // *    returns 12: '1.200'
    var n = !isFinite(+number) ? 0 : +number, 
        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
        dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
        toFixedFix = function (n, prec) {
            // Fix for IE parseFloat(0.55).toFixed(0) = 0;
            var k = Math.pow(10, prec);
            return Math.round(n * k) / k;
        },
        s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.');
    if (s[0].length > 3) {
        s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
    }
    if ((s[1] || '').length < prec) {
        s[1] = s[1] || '';
        s[1] += new Array(prec - s[1].length + 1).join('0');
    }
    return s.join(dec);
}

UPDATE 02/13/14

Ludzie donoszą, że to nie działa zgodnie z oczekiwaniami, więc zrobiłem js Fiddle , który obejmuje zautomatyzowane testy.

Aktualizacja 26/11/2017

Oto fiddle jako fragment stosu z nieco zmodyfikowanym wyjściem:

function number_format(number, decimals, dec_point, thousands_sep) {
    // http://kevin.vanzonneveld.net
    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     bugfix by: Michael White (http://getsprink.com)
    // +     bugfix by: Benjamin Lupton
    // +     bugfix by: Allan Jensen (http://www.winternet.no)
    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +     bugfix by: Howard Yeend
    // +    revised by: Luke Smith (http://lucassmith.name)
    // +     bugfix by: Diogo Resende
    // +     bugfix by: Rival
    // +      input by: Kheang Hok Chin (http://www.distantia.ca/)
    // +   improved by: davook
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Jay Klehr
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Amir Habibi (http://www.residence-mixte.com/)
    // +     bugfix by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +   improved by: Drew Noakes
    // *     example 1: number_format(1234.56);
    // *     returns 1: '1,235'
    // *     example 2: number_format(1234.56, 2, ',', ' ');
    // *     returns 2: '1 234,56'
    // *     example 3: number_format(1234.5678, 2, '.', '');
    // *     returns 3: '1234.57'
    // *     example 4: number_format(67, 2, ',', '.');
    // *     returns 4: '67,00'
    // *     example 5: number_format(1000);
    // *     returns 5: '1,000'
    // *     example 6: number_format(67.311, 2);
    // *     returns 6: '67.31'
    // *     example 7: number_format(1000.55, 1);
    // *     returns 7: '1,000.6'
    // *     example 8: number_format(67000, 5, ',', '.');
    // *     returns 8: '67.000,00000'
    // *     example 9: number_format(0.9, 0);
    // *     returns 9: '1'
    // *    example 10: number_format('1.20', 2);
    // *    returns 10: '1.20'
    // *    example 11: number_format('1.20', 4);
    // *    returns 11: '1.2000'
    // *    example 12: number_format('1.2000', 3);
    // *    returns 12: '1.200'
    var n = !isFinite(+number) ? 0 : +number, 
        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
        dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
        toFixedFix = function (n, prec) {
            // Fix for IE parseFloat(0.55).toFixed(0) = 0;
            var k = Math.pow(10, prec);
            return Math.round(n * k) / k;
        },
        s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.');
    if (s[0].length > 3) {
        s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
    }
    if ((s[1] || '').length < prec) {
        s[1] = s[1] || '';
        s[1] += new Array(prec - s[1].length + 1).join('0');
    }
    return s.join(dec);
}

var exampleNumber = 1;
function test(expected, number, decimals, dec_point, thousands_sep)
{
    var actual = number_format(number, decimals, dec_point, thousands_sep);
    console.log(
        'Test case ' + exampleNumber + ': ' +
        '(decimals: ' + (typeof decimals === 'undefined' ? '(default)' : decimals) +
        ', dec_point: "' + (typeof dec_point === 'undefined' ? '(default)' : dec_point) + '"' +
        ', thousands_sep: "' + (typeof thousands_sep === 'undefined' ? '(default)' : thousands_sep) + '")'
    );
    console.log('  => ' + (actual === expected ? 'Passed' : 'FAILED') + ', got "' + actual + '", expected "' + expected + '".');
    exampleNumber++;
}

test('1,235',    1234.56);
test('1 234,56', 1234.56, 2, ',', ' ');
test('1234.57',  1234.5678, 2, '.', '');
test('67,00',    67, 2, ',', '.');
test('1,000',    1000);
test('67.31',    67.311, 2);
test('1,000.6',  1000.55, 1);
test('67.000,00000', 67000, 5, ',', '.');
test('1',        0.9, 0);
test('1.20',     '1.20', 2);
test('1.2000',   '1.20', 4);
test('1.200',    '1.2000', 3);
.as-console-wrapper {
  max-height: 100% !important;
}
 89
Author: Kerry Jones,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-26 13:13:48

Jest to odmiana odpowiedzi @mikez302, ale zmodyfikowana, aby wspierać liczby z dziesiętnymi (za @ neu-rah ' s feedback that numberWithCommas(12345.6789) -> "12,345.6,789" zamiast "12,345. 6789"

function numberWithCommas(n) {
    var parts=n.toString().split(".");
    return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + (parts[1] ? "." + parts[1] : "");
}
 65
Author: user1437663,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-05 15:03:10
function formatNumber (num) {
    return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}

print(formatNumber(2665));      // 2,665
print(formatNumber(102665));    // 102,665
print(formatNumber(111102665)); // 111,102,665
 55
Author: Tutankhamen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-19 06:47:01

Dzięki wszystkim za odpowiedzi. Zbudowałem na podstawie niektórych odpowiedzi, aby stworzyć bardziej uniwersalne rozwiązanie.

PIERWSZY fragment dodaje funkcję, która naśladuje PHP ' S number_format() do prototypu numeru. Jeśli formatuję liczbę, zwykle chcę miejsc dziesiętnych, więc funkcja przyjmuje liczbę miejsc dziesiętnych, aby pokazać. Niektóre kraje używają przecinków jako separatora dziesiętnego i dziesiętnego jako separatora tysięcy, więc funkcja umożliwia te separatory gotowi.

Number.prototype.numberFormat = function(decimals, dec_point, thousands_sep) {
    dec_point = typeof dec_point !== 'undefined' ? dec_point : '.';
    thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ',';

    var parts = this.toFixed(decimals).split('.');
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousands_sep);

    return parts.join(dec_point);
}

Użyłbyś tego w następujący sposób:

var foo = 5000;
console.log(foo.numberFormat(2)); // us format: 5,000.00
console.log(foo.numberFormat(2, ',', '.')); // european format: 5.000,00

Odkryłem, że często potrzebowałem odzyskać liczbę do operacji matematycznych, ale parseFloat konwertuje 5000 na 5, po prostu przyjmując pierwszą sekwencję wartości całkowitych. Stworzyłem więc własną funkcję konwersji float i dodałem ją do prototypu String.

String.prototype.getFloat = function(dec_point, thousands_sep) {
    dec_point = typeof dec_point !== 'undefined' ? dec_point : '.';
    thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ',';

    var parts = this.split(dec_point);
    var re = new RegExp("[" + thousands_sep + "]");
    parts[0] = parts[0].replace(re, '');

    return parseFloat(parts.join(dec_point));
}

Teraz możesz używać obu funkcji w następujący sposób:

var foo = 5000;
var fooString = foo.numberFormat(2); // The string 5,000.00
var fooFloat = fooString.getFloat(); // The number 5000;

console.log((fooString.getFloat() + 1).numberFormat(2)); // The string 5,001.00
 31
Author: J.Money,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-08 21:51:29

Intl.NumberFormat

Natywna funkcja JS. Obsługiwane przez IE11, Edge, najnowsze Safari, Chrome, Firefox, Opera, Safari na iOS i Chrome na Androida.

var number = 3500;

console.log(new Intl.NumberFormat().format(number));
// → '3,500' if in US English locale
 29
Author: lonelyloner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-14 16:21:23

Używanie wyrażenia regularnego

function toCommas(value) {
    return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
console.log(toCommas(123456789)); // 123,456,789
console.log(toCommas(1234567890)); // 1,234,567,890
console.log(toCommas(1234)); // 1,234

Korzystanie z toLocaleString()

var number = 123456.789;

// request a currency format
console.log(number.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }));
// → 123.456,79 €

// the Japanese yen doesn't use a minor unit
console.log(number.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' }))
// → ¥123,457

// limit to three significant digits
console.log(number.toLocaleString('en-IN', { maximumSignificantDigits: 3 }));
// → 1,23,000

Ref MDN: Liczba.prototyp.toLocaleString()

Korzystanie Z Intl.NumberFormat()

var number = 123456.789;

console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(number));
// expected output: "123.456,79 €"

// the Japanese yen doesn't use a minor unit
console.log(new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(number));
// expected output: "¥123,457"

// limit to three significant digits
console.log(new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(number));
// expected output: "1,23,000"

Ref Intl.NumberFormat

DEMO TUTAJ

<script type="text/javascript">
  // Using Regular expression
  function toCommas(value) {
    return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  }

  function commas() {
    var num1 = document.myform.number1.value;

    // Using Regular expression
    document.getElementById('result1').value = toCommas(parseInt(num1));
    // Using toLocaleString()
    document.getElementById('result2').value = parseInt(num1).toLocaleString('ja-JP', {
      style: 'currency',
      currency: 'JPY'
    });
    // Using Intl.NumberFormat()
    document.getElementById('result3').value = new Intl.NumberFormat('ja-JP', {
      style: 'currency',
      currency: 'JPY'
    }).format(num1);
  }
</script>
<FORM NAME="myform">
  <INPUT TYPE="text" NAME="number1" VALUE="123456789">
  <br>
  <INPUT TYPE="button" NAME="button" Value="=>" onClick="commas()">
  <br>Using Regular expression
  <br>
  <INPUT TYPE="text" ID="result1" NAME="result1" VALUE="">
  <br>Using toLocaleString()
  <br>
  <INPUT TYPE="text" ID="result2" NAME="result2" VALUE="">
  <br>Using Intl.NumberFormat()
  <br>
  <INPUT TYPE="text" ID="result3" NAME="result3" VALUE="">

</FORM>
 28
Author: TinhNQ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-17 01:30:52

Myślę, że jest to najkrótsze Wyrażenie regularne, które to robi:

/\B(?=(\d{3})+\b)/g

"123456".replace(/\B(?=(\d{3})+\b)/g, ",")
Sprawdziłem na kilku numerach i zadziałało.
 22
Author: user3664916,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-13 07:50:38

Number.prototype.toLocaleString() byłoby super, gdyby była dostarczana natywnie przez wszystkie przeglądarki (Safari) .

Sprawdziłam wszystkie inne odpowiedzi, ale nikt nie zdawał się ich wypełniać. Oto poc w kierunku tego, który jest w rzeczywistości kombinacją dwóch pierwszych odpowiedzi; jeśli toLocaleString działa, używa go, jeśli nie używa funkcji niestandardowej.

var putThousandsSeparators;

putThousandsSeparators = function(value, sep) {
  if (sep == null) {
    sep = ',';
  }
  // check if it needs formatting
  if (value.toString() === value.toLocaleString()) {
    // split decimals
    var parts = value.toString().split('.')
    // format whole numbers
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, sep);
    // put them back together
    value = parts[1] ? parts.join('.') : parts[0];
  } else {
    value = value.toLocaleString();
  }
  return value;
};

alert(putThousandsSeparators(1234567.890));
 18
Author: Sinan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-03 05:46:26

Separator tysięcy można wstawić w sposób międzynarodowy, używając obiektu Intl przeglądarki:

Intl.NumberFormat().format(1234);
// returns "1,234" if the user's locale is en_US, for example

Zobacz artykuł MDN na NumberFormat aby dowiedzieć się więcej, możesz określić zachowanie lokalne lub domyślne użytkownika. jest to trochę bardziej niezawodne, ponieważ szanuje lokalne różnice; wiele krajów używa okresów do oddzielania cyfr, podczas gdy przecinek oznacza dziesiętne.

Intl.NumberFormat nie jest jeszcze dostępny we wszystkich przeglądarkach, ale działa w najnowszej Chrome, Opera, & IE. Kolejne wydanie Firefoksa powinno go obsługiwać. Wydaje się, że Webkit nie ma osi czasu wdrożenia.

 15
Author: phette23,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-26 01:43:16

Jeśli masz do czynienia z wartościami walut i formatowaniem to może warto dodać małe księgowość.js , który obsługuje wiele przypadków krawędzi i lokalizacji:

// Default usage:
accounting.formatMoney(12345678); // $12,345,678.00

// European formatting (custom symbol and separators), could also use options object as second param:
accounting.formatMoney(4999.99, "€", 2, ".", ","); // €4.999,99

// Negative values are formatted nicely, too:
accounting.formatMoney(-500000, "£ ", 0); // £ -500,000

// Simple `format` string allows control of symbol position [%v = value, %s = symbol]:
accounting.formatMoney(5318008, { symbol: "GBP",  format: "%v %s" }); // 5,318,008.00 GBP
 13
Author: ShitalShah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-25 17:40:57

Poniższy kod wykorzystuje skanowanie znaków, więc nie ma wyrażeń regularnych.

function commafy( num){
  var parts = (''+(num<0?-num:num)).split("."), s=parts[0], L, i=L= s.length, o='';
  while(i--){ o = (i===0?'':((L-i)%3?'':',')) 
                  +s.charAt(i) +o }
  return (num<0?'-':'') + o + (parts[1] ? '.' + parts[1] : ''); 
}

Pokazuje obiecujące wyniki: http://jsperf.com/number-formatting-with-commas/5

2015.4.26: Drobne poprawki, aby rozwiązać problem, gdy liczba https://jsfiddle.net/runsun/p5tqqvs3/

 12
Author: runsun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-24 21:31:31

Możesz użyć tej procedury do sformatowania potrzebnej waluty.

var nf = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});
nf.format(123456.789); // ‘$123,456.79’

Aby uzyskać więcej informacji, możesz uzyskać dostęp do tego linku.

Https://www.justinmccandless.com/post/formatting-currency-in-javascript/

 12
Author: Dulith De Cozta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-07 21:46:41

Oto prosta funkcja wstawiająca przecinki dla tysięcy separatorów. Używa funkcji tablicowych zamiast wyrażeń regularnych.

/**
 * Format a number as a string with commas separating the thousands.
 * @param num - The number to be formatted (e.g. 10000)
 * @return A string representing the formatted number (e.g. "10,000")
 */
var formatNumber = function(num) {
    var array = num.toString().split('');
    var index = -3;
    while (array.length + index > 0) {
        array.splice(index, 0, ',');
        // Decrement by 4 since we just added another unit to the array.
        index -= 4;
    }
    return array.join('');
};
 9
Author: Noah Freitas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-02 16:51:39

Napisałam to zanim natknęłam się na ten post. Brak regex i można rzeczywiście zrozumieć kod.

$(function(){
  
  function insertCommas(s) {

    // get stuff before the dot
    var d = s.indexOf('.');
    var s2 = d === -1 ? s : s.slice(0, d);

    // insert commas every 3 digits from the right
    for (var i = s2.length - 3; i > 0; i -= 3)
      s2 = s2.slice(0, i) + ',' + s2.slice(i);

    // append fractional part
    if (d !== -1)
      s2 += s.slice(d);

    return s2;

  }
  
  
  $('#theDudeAbides').text( insertCommas('1234567.89012' ) );
  
  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div id="theDudeAbides"></div>
 8
Author: Ronnie Overby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-25 21:41:06

Spróbuję poprawić uKolka ' S odpowiedź i może pomóc innym zaoszczędzić trochę czasu.

Użyj Cyfry.js .

document.body.textContent = numeral(1234567).format('0,0');
<script src="//cdnjs.cloudflare.com/ajax/libs/numeral.js/1.4.5/numeral.min.js"></script>

Powinieneś wybrać numer.prototyp.toLocaleString () Tylko jeśli jego kompatybilność z przeglądarką nie stanowi problemu.

 6
Author: Beder Acosta Borges,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:48

Dla mnie najlepszą odpowiedzią jest użycie toLocaleString, jak powiedzieli niektórzy członkowie. Jeśli chcesz dołączyć symbol ' $ ' po prostu dodaj languaje i wpisz Opcje. Oto i przykład sformatowania liczby na Meksykańskie peso

var n = 1234567.22
alert(n.toLocaleString("es-MX",{style:"currency", currency:"MXN"}))

Skrót

1234567.22.toLocaleString("es-MX",{style:"currency", currency:"MXN"})
 5
Author: Carlos A. Ortiz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-18 18:45:33

Myślę, że ta funkcja zajmie się wszystkimi kwestiami związanymi z tym problemem.

function commaFormat(inputString) {
    inputString = inputString.toString();
    var decimalPart = "";
    if (inputString.indexOf('.') != -1) {
        //alert("decimal number");
        inputString = inputString.split(".");
        decimalPart = "." + inputString[1];
        inputString = inputString[0];
        //alert(inputString);
        //alert(decimalPart);

    }
    var outputString = "";
    var count = 0;
    for (var i = inputString.length - 1; i >= 0 && inputString.charAt(i) != '-'; i--) {
        //alert("inside for" + inputString.charAt(i) + "and count=" + count + " and outputString=" + outputString);
        if (count == 3) {
            outputString += ",";
            count = 0;
        }
        outputString += inputString.charAt(i);
        count++;
    }
    if (inputString.charAt(0) == '-') {
        outputString += "-";
    }
    //alert(outputString);
    //alert(outputString.split("").reverse().join(""));
    return outputString.split("").reverse().join("") + decimalPart;
}
 4
Author: AbhinavRanjan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-16 22:00:47
var formatNumber = function (number) {
  var splitNum;
  number = Math.abs(number);
  number = number.toFixed(2);
  splitNum = number.split('.');
  splitNum[0] = splitNum[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  return splitNum.join(".");
}
 3
Author: Kiry Meas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-10 18:38:49

Dodałem tofixed do aki143s'S rozwiązanie. Rozwiązanie to wykorzystuje kropki dla separatorów tysięcy i przecinki dla precyzji.

function formatNumber( num, fixed ) { 
    var decimalPart;

    var array = Math.floor(num).toString().split('');
    var index = -3; 
    while ( array.length + index > 0 ) { 
        array.splice( index, 0, '.' );              
        index -= 4;
    }

    if(fixed > 0){
        decimalPart = num.toFixed(fixed).split(".")[1];
        return array.join('') + "," + decimalPart; 
    }
    return array.join(''); 
};

Przykłady;

formatNumber(17347, 0)  = 17.347
formatNumber(17347, 3)  = 17.347,000
formatNumber(1234563.4545, 3)  = 1.234.563,454
 2
Author: bartburkhardt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-08 12:47:33

Myślę, że Twoje rozwiązanie jest jednym z krótszych, jakie widziałem. Nie sądzę, że istnieją jakieś standardowe funkcje JavaScript do tego rodzaju rzeczy, więc prawdopodobnie jesteś zdany na siebie.

Sprawdziłem specyfikacje CSS 3, aby zobaczyć, czy jest to możliwe w CSS, ale jeśli nie chcesz, aby każda cyfra miała swoją własną <span>, nie sądzę, że jest to możliwe.

Znalazłem jeden projekt na Google Code, który wyglądał obiecująco: flexible-js-formatowanie . Nie używałem to, ale wygląda dość elastycznie i ma testy jednostkowe za pomocą JsUnit . Deweloper ma również wiele postów (choć starych) na ten temat.

Pamiętaj o międzynarodowych użytkownikach: wiele krajów używa spacji jako separatora i używa przecinka do oddzielania dziesiętnego od integralnej części liczby.

 2
Author: jasonmp85,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-08 13:58:11

Wiele dobrych odpowiedzi już. Oto kolejny, tylko dla zabawy:

function format(num, fix) {
    var p = num.toFixed(fix).split(".");
    return p[0].split("").reduceRight(function(acc, num, i, orig) {
        if ("-" === num && 0 === i) {
            return num + acc;
        }
        var pos = orig.length - i - 1
        return  num + (pos && !(pos % 3) ? "," : "") + acc;
    }, "") + (p[1] ? "." + p[1] : "");
}

Niektóre przykłady:

format(77.03453, 2); // "77.03"
format(78436589374); // "78,436,589,374"
format(784, 4);      // "784.0000"
format(-123456);     // "-123,456"
 2
Author: Wayne Burkett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-13 17:38:15

Oto moja próba:

EDIT: dodano w dziesiętnych

function splitMille(n, separator = ',') {
  // Cast to string
  let num = (n + '')

  // Test for and get any decimals (the later operations won't support them)
  let decimals = ''
  if (/\./.test(num)) {
    // This regex grabs the decimal point as well as the decimal numbers
    decimals = num.replace(/^.*(\..*)$/, '$1')
  }
  
  // Remove decimals from the number string
  num = num.replace(decimals, '')
    // Reverse the number string through Array functions
    .split('').reverse().join('')
    // Split into groups of 1-3 characters (with optional supported character "-" for negative numbers)
    .match(/[0-9]{1,3}-?/g)
    // Add in the mille separator character and reverse back
    .join(separator).split('').reverse().join('')

  // Put the decimals back and output the formatted number
  return `${num}${decimals}`
}

let testA = splitMille(1234)
let testB = splitMille(-1234)
let testC = splitMille(123456.789)
let testD = splitMille(9007199254740991)
let testE = splitMille(1000.0001)

console.log('Results!\n\tA: %s\n\tB: %s\n\tC: %s\n\tD: %s\n\tE: %s', testA, testB, testC, testD, testE)
 2
Author: Matt Scheurich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-28 15:49:56

Po Nie znalezieniu nowoczesnego i kompleksowego rozwiązania, napisałem funkcję strzałki (bez regex), aby rozwiązać problem formatowania i pozwala dzwoniącemu podać numer cyfr ułamkowych , a także separator kropek i tysięcy dla Europy i reszty świata.

Przykłady:

numberFormatter(1234567890.123456) => 1,234,567,890
numberFormatter(1234567890.123456, 4) => 1,234,567,890.1235
numberFormatter(1234567890.123456, 4, '.', ',') => 1.234.567.890,1235 Europe

Oto funkcja zapisana w ES6 (nowoczesna składnia):

const numberFormatter = (number, fractionDigits = 0, thousandSeperator = ',', fractionSeperator = '.') => {
    if (number!==0 && !number || !Number.isFinite(number)) return number
    const frDigits = Number.isFinite(fractionDigits)? Math.min(Math.max(fractionDigits, 0), 7) : 0
    const num = number.toFixed(frDigits).toString()

    const parts = num.split('.')
    let digits = parts[0].split('').reverse()
    let sign = ''
    if (num < 0) {sign = digits.pop()}
    let final = []
    let pos = 0

    while (digits.length > 1) {
        final.push(digits.shift())
        pos++
        if (pos % 3 === 0) {final.push(thousandSeperator)}
    }
    final.push(digits.shift())
    return `${sign}${final.reverse().join('')}${frDigits > 0 ? fractionSeperator : ''}${frDigits > 0 && parts[1] ? parts[1] : ''}`
}

Został przetestowany pod kątem negatywnego, złego wejścia i Nan cases . Jeśli Dane wejściowe to nan , to po prostu je zwraca.

 2
Author: Hannes Sverrisson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-14 18:47:04

Rozwiązanie z @ user1437663 jest świetne.

Kto naprawdę rozumie rozwiązanie jest przygotowany do zrozumienia złożonych wyrażeń regularnych.

Mała poprawa, aby uczynić go bardziej czytelnym:

function numberWithCommas(x) {
    var parts = x.toString().split(".");
    return parts[0].replace(/\B(?=(\d{3})+(?=$))/g, ",") + (parts[1] ? "." + parts[1] : "");
}

Wzór zaczyna się od \b, aby uniknąć przecinków na początku wyrazu. Co ciekawe, wzór jest zwracany jako pusty, ponieważ \b nie przesuwa "kursora" (to samo dotyczy $).

O \B następuje mniej znane zasoby, ale jest potężną cechą wyrażeń regularnych Perla.

            Pattern1 (? = (Pattern2) ).

Magia polega na tym, że to, co jest w nawiasach ( Pattern2 ) jest wzorcem, który podąża za poprzednim wzorcem (Pattern1), ale bez przesuwania kursora, a także nie jest częścią zwracanego wzorca. Jest to swego rodzaju wzór przyszłości. To jest podobne, gdy ktoś patrzy do przodu, ale naprawdę nie chodzi!

W tym przypadku Wzorzec 2 jest

\d{3})+(?=$)

To znaczy 3 cyfry (jeden lub więcej razy), po których następuje koniec łańcucha ($)

Wreszcie, Replace metoda zmienia wszystkie wystąpienia znalezionego wzorca (pusty łańcuch) dla przecinka. Dzieje się tak tylko wtedy, gdy pozostała część jest wielokrotnością 3 cyfr (takie przypadki, w których przyszły kursor dociera do końca źródła).

 1
Author: Paulo Buchsbaum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-12 20:17:03

Oto dobre rozwiązanie z mniejszą ilością kodowania...

var y = "";
var arr = x.toString().split("");
for(var i=0; i<arr.length; i++)
{
    y += arr[i];
    if((arr.length-i-1)%3==0 && i<arr.length-1) y += ",";
}
 1
Author: Mosiur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-14 07:36:45

Alternatywny sposób, wspierający liczby dziesiętne, różne separatory i negatywy.

var number_format = function(number, decimal_pos, decimal_sep, thousand_sep) {
    var ts      = ( thousand_sep == null ? ',' : thousand_sep )
        , ds    = ( decimal_sep  == null ? '.' : decimal_sep )
        , dp    = ( decimal_pos  == null ? 2   : decimal_pos )

        , n     = Math.abs(Math.ceil(number)).toString()

        , i     = n.length % 3 
        , f     = n.substr(0, i)
    ;

    if(number < 0) f = '-' + f;

    for(;i<n.length;i+=3) {
        if(i!=0) f+=ts;
        f+=n.substr(i,3);
    }

    if(dp > 0) 
        f += ds + number.toFixed(dp).split('.')[1]

    return f;
}
 1
Author: Felipe Buccioni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-14 05:50:56

Dostosowałem Twój kod do pracy w TextBox (Input type = "text"), dzięki czemu możemy wprowadzać i usuwać cyfry w czasie rzeczywistym bez utraty kursora. Działa również, jeśli wybierzesz Zakres po usunięciu. I możesz swobodnie używać strzałek i przycisków home / end.
Dzięki za oszczędność mojego czasu!

//function controls number format as "1,532,162.3264321"
function numberWithCommas(x) {
    var e = e || window.event;
    if (e.keyCode >= '35' && e.keyCode <= '40') return; //skip arrow-keys
    var selStart = x.selectionStart, selEnd = x.selectionEnd; //save cursor positions
    var parts = x.value.toString().split(".");
    var part0len = parts[0].length; //old length to check if new ',' would be added. Need for correcting new cursor position (+1 to right).

    //if user deleted ',' - remove previous number instead (without selection)
    if (x.selectionLength == 0 && (e.keyCode == 8 || e.keyCode == 46)) {//if pressed 8-backspace or 46-delete button
        var delPos = parts[0].search(/\d{4}/);
        if (delPos != -1) {//if found 4 digits in a row (',' is deleted)
            if (e.keyCode == 8) {//if backspace flag
                parts[0] = parts[0].slice(0, selStart - 1) + parts[0].slice(selEnd, parts[0].length);
                selEnd--;
                if (selStart > selEnd) selStart = selEnd;
            } else {
                parts[0] = parts[0].slice(0, selStart) + parts[0].slice(selEnd + 1, parts[0].length);
                selStart++;
                if (selEnd < selStart) selEnd = selStart;
            }
        }
    }

   var hasMinus = parts[0][0] == '-';
   parts[0] = (hasMinus ? '-' : '') + parts[0].replace(/[^\d]*/g, ""); //I'd like to clear old ',' to avoid things like 1,2,3,5,634.443216
   parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); //sets ',' between each 3 digits
   if (part0len < parts[0].length) { //move cursor to right if added new ','
       selStart++;
       selEnd++;
   } else if (part0len > parts[0].length) { //..or if removed last one ','
       selStart--;
       selEnd--;
   }
   x.value = parts.join(".");
   x.setSelectionRange(selStart, selEnd); //restoring cursor position
}
function saveSelectionLength(x) {
    x.selectionLength = x.selectionEnd - x.selectionStart;
}

Aby użyć tego właśnie dodano dwa zdarzenia-onKeyUp i onKeyDown

<asp:TextBox runat="server" ID="val" Width="180px" onKeyUp="numberWithCommas(this);" onKeyDown="saveSelectionLength(this);"/>
 1
Author: Eluny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-23 16:29:56