Как напечатать число с запятыми в качестве разделителей тысяч в JavaScript

1785

Я пытаюсь напечатать целое число в JavaScript с запятыми в качестве разделителей тысяч. Например, я хочу показать число 1234567 как «1,234,567». Как бы я поступил так?

Вот как я это делаю:

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

Есть ли более простой или более элегантный способ сделать это? Было бы хорошо, если бы он работал и с поплавками, но это не обязательно. Он не должен зависеть от локали, чтобы выбирать между точками и запятыми.

Элиас Замария
источник
156
Number (x) .toLocaleString ()
Боффин
@Boffin это не работает для номера типа ввода (из-за запятых) - в принятом ответе мы можем заменить запятую на точку, и номер типа ввода будет работать
Виталий Зданевич
48
Стоит отметить, что Number.prototype.toLocaleString до сих пор не работает Safari, в 2016 году . Вместо фактического форматирования числа, оно просто возвращает его, без ошибок. Получив сегодня самый большой лицевой
маску
Тем не менее, он работает в iOS-сафари.
Тим
toLocaleString несовместим и не должен использоваться. Например - в Firefox это вернет 1,234, но в IE это добавит десятичные дроби: 1234.00
Борт

Ответы:

2840

Я использовал идею из ответа Керри, но упростил ее, так как я просто искал что-то простое для моей конкретной цели. Вот что я сделал:

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


Регулярное выражение использует 2 утверждения предпросмотра:

  • положительный, чтобы искать любую точку в строке, которая имеет несколько из трех цифр подряд после нее,
  • отрицательное утверждение, чтобы удостовериться, что у этой точки есть только кратное 3 цифрам. Выражение замены ставит там запятую.

Например, если вы передадите его 123456789.01, положительное утверждение будет соответствовать каждому пятну слева от 7 (так 789как кратно 3 цифрам, 678кратно 3 цифрам 567и т. Д.). Отрицательное утверждение проверяет, что кратное 3 цифрам не имеет никаких цифр после него. 789после него стоит точка, поэтому она точно кратна 3 цифрам, поэтому запятая идет туда. 678является кратным 3 цифрам, но после него есть 9после него, поэтому эти 3 цифры являются частью группы из 4, и запятая здесь не идет. Аналогично для 567. 4567896 цифр, что кратно 3, поэтому перед этим стоит запятая. 345678кратен 3, но имеет 9после него, поэтому запятая не идет. И так далее. \B не позволяет регулярному выражению ставить запятую в начале строки.

@ neu-rah упомянул, что эта функция добавляет запятые в нежелательные места, если после десятичной точки больше 3 цифр. Если это проблема, вы можете использовать эту функцию:

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

@ tjcrowder отметил, что теперь, когда JavaScript имеет lookbehind ( информация о поддержке ), его можно решить в самом регулярном выражении:

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

(?<!\.\d*)является отрицательным взглядом, который говорит, что совпадению не может предшествовать .ноль или более цифр. Отрицательная быстрее просмотра назад , чем splitи joinрешения ( сравнение ), по крайней мере , в V8.

Элиас Замария
источник
21
Очень круто, заметил, что у него проблемы с числами, которые имеют более 3 знаков после запятой.
Эрик Петроэле
60
попробуй numberWithCommas (12345.6789) -> "12,345.6,789" мне не нравится
neu-rah
4
Это не очень хорошо работает с дробями, мы не хотим запятых после десятичной точки
Mugen
30
Небольшое улучшение, которое исправляется после «.» задача '123456789.01234'. место (/ \ B (? = (? = \ d * \.) (\ d {3}) + (?! \ d)) / g, '_')
Дмитрий Голубев
8
@DmitrijGolubev Не работает для целых чисел. Возможно, форсирование десятичной точки было бы решением.
Влад
1811

Я удивлен, что никто не упомянул Number.prototype.toLocaleString . Он реализован в JavaScript 1.5 (который был представлен в 1999 году), поэтому он в основном поддерживается во всех основных браузерах.

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

Это также работает в Node.js с v0.12 через включение Intl

Просто обратите внимание, что эта функция возвращает строку, а не число.

Если вы хотите что-то другое, Numeral.js может быть интересным.

uKolka
источник
17
@csigrist Хорошие моменты, но это не так плохо, как кажется. Скорость зависит от браузера. В FF или Opera это хорошо работает. Я впитываю Chrome все же. Что касается нулей: var number = 123456.000; number.toLocaleString('en-US', {minimumFractionDigits: 2}); "123,456.00"эти опции не работают в FF или Safari.
uKolka
22
Разница в производительности может или не может быть проблемой, в зависимости от контекста. Если использовать для гигантской таблицы из 1000 результатов, это будет более важно, но если использовать только для одного значения, разница незначительна. Но преимущество в том, что он осведомлен о локали, поэтому кто-то в Европе увидит 34,523,453,345 или 34 523 453 345 . Это было бы более важно на сайте с посетителями из многих стран.
T Nguyen
6
Потрясающие. Наконец-то ответ с нативной функцией. И что более того, этот правильно отображается в разных странах с разными разделителями (в Чехии мы пишем X XXX XXX,YYY).
Томаш Зато - Восстановить Монику
22
Обновление для googlers: toLocaleStringработает в Node.js с v0.12 через включение Intl .
Сробинсон
8
@MSC вы должны попробовать parseInt("1234567", 10).toLocaleString('en-US', {minimumFractionDigits: 2})или new Number("1234567").toLocaleString('en-US', {minimumFractionDigits: 2})вместо этого. Это не работает, потому что вы используете его в строке, а не в числе.
uKolka
244
var number = 1234567890; // Example number to be converted

⚠ Имейте в виду, что максимальное целочисленное значение javascript составляет 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 не поддерживается):

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

Из того, что я проверял (по крайней мере, Firefox), они более или менее одинаковы в отношении производительности.

VSync
источник
6
NumberFormat не поддерживается в Safari для тех, кто там реализует.
Марковега
6
toLocaleString также не поддерживается в сафари
Deepak Banka
3
Поддержка браузеров всегда упоминается внизу каждой страницы MDN, на которую я ссылаюсь.
vsync
5
основные toLocaleStringработы по сафари, варианты не
dandavis
3
toLocaleStringрешение , вероятно , следует также включать в требуемом языке, таким образом toLocaleString("en"), потому что английский шаблон использует запятые. Тем не менее, если toLocaleString()во Франции не используется индикатор локали, он будет давать точки вместо запятых, потому что это то, что используется для локального разделения тысяч.
Майк 'Pomax' Камерманс
112

Я предлагаю использовать 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);
}

ОБНОВЛЕНИЕ 13/13/14

Люди сообщают, что это работает не так, как ожидалось, поэтому я сделал JS Fiddle, который включает в себя автоматические тесты.

Обновление 26/11/2017

Вот эта скрипка в виде фрагмента стека с немного измененным выводом:

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

Керри Джонс
источник
Не то чтобы я это записал, но я верю, что люди так и сделали, потому что это не работает. Я считаю, что даже некоторые из ваших тестов не работают.
Андрей С
3
@ Андрей S - Только 1 человек отметил это. Это работает, я использовал это в своем собственном коде много раз. Это также не мой код (ни мои тесты), я ссылался на сайт, с которого он пришел, который является известным сайтом. Возможно, у них есть обновленная версия), так как код, который вы просматриваете, 3 года.
Керри Джонс
13
@ernix - оператор попросил JavaScript, ответ, который я дал - JavaScript. Это интерпретация JavaScript функции PHP.
Керри Джонс
2
@ernix - работает точно так же, как и ожидалось с примером, приведенным OP. Я положил скрипку, чтобы вы могли видеть.
Керри Джонс
4
@ernix - Хорошо, но дело в том, что он делает именно то, что просил ОП. Это с другого сайта (не поддерживается мной, и я уже говорил об этом ранее), и при задании правильных переменных он работает точно так, как указано. Если вы считаете, что это ошибка, свяжитесь с phpjs.org или посмотрите, есть ли у них обновленная версия.
Керри Джонс
75

Это вариант ответа @ mikez302, но он изменен для поддержки чисел с десятичными числами (согласно отзыву @ neu-rah о числеWithCommas (12345.6789) -> «12 345,6 789» вместо «12 345,6789»

function numberWithCommas(n) {
    var parts=n.toString().split(".");
    return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + (parts[1] ? "." + parts[1] : "");
}
user1437663
источник
67
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
Тутанхамон
источник
Что это делает, что мой ответ не делает? Регулярное выражение выглядит немного иначе, но похоже, что оно должно делать то же самое.
Элиас Замария
8
короче :)
Тутанхамон
4
Это элегантно. Именно то, что я искал.
традиционное
4
Из blog.tompawlak.org/number-currency-formatting-javascript ? Известная проблема: formatNumber (0.123456) = 0.123.456 Отсутствие в JS lookbehind затрудняет исправление с помощью элегантного регулярного выражения.
Влад
1
123456789.123456789.toString (). Replace (/ (\ d) (? = (\ D {3}) + \.) / G, '$ 1,') => 123 456
789.12345679
53

Использование регулярного выражения

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

Использование 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: Number.prototype.toLocaleString ()

Использование 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

ДЕМО НА ЗДЕСЬ

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

Представление

Представление http://jsben.ch/sifRd

Тинь Нго Куанг
источник
Это не работает, если вы печатаете динамически. Если вы просто даете ему значение, оно работает, но если вы вводите значение постоянно динамически, запятые добавляются в неправильном месте.
Эдгар Кинтеро
Я обновил демо ниже моего ответа. При вводе динамического значения в текстовое поле. попробуйте @EdgarQuintero
Ngô Quang
39

Intl.NumberFormat

Родная функция JS. Поддерживаются IE11, Edge, последние версии Safari, Chrome, Firefox, Opera, Safari для iOS и Chrome для Android.

var number = 3500;

console.log(new Intl.NumberFormat().format(number));
// → '3,500' if in US English locale
Дастин Сан
источник
Мой ответ был обновлен в ответ на ваши комментарии. Спасибо!
Дастин Сан
35

Спасибо всем за их ответы. Я построил некоторые ответы, чтобы создать более универсальное решение.

Первый фрагмент кода добавляет функцию , которая имитирует PHP «S number_format()на номер прототипа. Если я форматирую число, я обычно хочу использовать десятичные разряды, чтобы функция принимала количество отображаемых десятичных разрядов. Некоторые страны используют запятые в качестве десятичного разделителя и десятичного разделителя в качестве разделителя тысяч, поэтому функция позволяет устанавливать эти разделители.

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

Вы бы использовали это следующим образом:

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

Я обнаружил, что мне часто нужно возвращать число для математических операций, но parseFloat преобразует 5000 в 5, просто принимая первую последовательность целочисленных значений. Поэтому я создал свою собственную функцию преобразования с плавающей точкой и добавил ее в прототип 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));
}

Теперь вы можете использовать обе функции следующим образом:

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
Никто
источник
2
Очень хорошо, я позаимствовал первый метод;) Но он не дает правильного результата, если вы хотите использовать европейский формат, а число является дробным. Строка 5 должна быть:var parts = this.toFixed(decimals).toString().split('.');
vbwx
Вы правы! toFixed () меняет запятую на точку и поэтому '.' следует использовать вместо var dec_point. Спасибо что подметил это.
Нет
Вы можете сделать модуль npm для этого?
Чови
3
@ J.Money .toString не требуется, toFixed уже возвращает строку.
Ариэль
Я не знаю, почему вы упомянули здесь PHP вообще или дали прототипную функцию, которая уже существует
vsync
27

Я впечатлен количеством ответов на этот вопрос. Мне нравится ответ от uKolka :

n.toLocaleString()

Но, к сожалению, в некоторых регионах, таких как испанский, он не работает (IMHO), как ожидается, для чисел ниже 10000:

Number(1000).toLocaleString('ES-es')

Дает 1000и нет 1.000.

Посмотрите, чтобы toLocaleString не работал на числах меньше 10000 во всех браузерах, чтобы знать почему.

Поэтому мне пришлось воспользоваться ответом Элиаса Замарии, выбрав правильный символ разделения тысяч:

n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, Number(10000).toLocaleString().substring(2, 3))

Этот работает хорошо как одна строка для обоих языков, которые используют ,или .как разделитель тысяч и начинает работать с 1000 во всех случаях.

Number(1000).toString().replace(/\B(?=(\d{3})+(?!\d))/g, Number(10000).toLocaleString().substring(2, 3))

Дает 1.000с контекстом испанской локали.

Если вы хотите иметь абсолютный контроль над форматированием числа, вы также можете попробовать следующее:

let number   = 1234.567
let decimals = 2
let decpoint = '.' // Or Number(0.1).toLocaleString().substring(1, 2)
let thousand = ',' // Or Number(10000).toLocaleString().substring(2, 3)

let n = Math.abs(number).toFixed(decimals).split('.')
n[0] = n[0].split('').reverse().map((c, i, a) =>
  i > 0 && i < a.length && i % 3 == 0 ? c + thousand : c
).reverse().join('')
let final = (Math.sign(number) < 0 ? '-' : '') + n.join(decpoint)

console.log(final)

Дает 1,234.57.

Этот не нуждается в регулярном выражении. Он работает, toFixedсначала подгоняя число к желаемому количеству десятичных знаков , а затем разделяя его на десятичную точку, .если она есть. Затем левая сторона превращается в массив цифр, который переворачивается. Затем разделитель тысяч добавляется каждые три цифры от начала, и результат снова меняется на противоположный. Конечный результат - объединение двух частей. Знак входного номера Math.absсначала удаляется, а затем при необходимости возвращается.

Это не однострочник, но не намного дольше и легко превращается в функцию. Переменные были добавлены для ясности, но они могут быть заменены их желаемыми значениями, если они известны заранее. Вы можете использовать выражения, которые используются toLocaleStringдля определения правильных символов для десятичной точки и разделителя тысяч для текущей локали (имейте в виду, что для них требуется более современный Javascript.)

Хавьер Элис
источник
23

Я думаю, что это самое короткое регулярное выражение, которое делает это:

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

"123456".replace(/\B(?=(\d{3})+\b)/g, ",")

Я проверил это на нескольких числах, и это сработало.

user3664916
источник
работает только хорошо, если у вас нет числа с плавающей запятой с более чем 3 числами после разделителя, в данном случае это точка. В противном случае это также добавляет запятую. "1234567890.1234567890" .replace (/ \ B (? = (\ D {3}) + \ b) / g, ",") Это не будет работать, например. Возвращает «1 234 567 890,1 234 567 890»
Марсио
1
Работает хорошо для валюты, хотя! Просто округлите цифры перед добавлением запятых.
Кайл Чадха,
1
После десятичной точки добавляется: 12.3456 ".replace (/ \ B (? = (\ D {3}) + \ b) / g,", ") == 12.3456
Шри Тивари
21

Number.prototype.toLocaleString()было бы здорово, если бы он был предоставлен всеми браузерами (Safari) .

Я проверил все остальные ответы, но никто, казалось, не заполнил его. Вот пример того, что на самом деле является комбинацией первых двух ответов; если toLocaleStringработает, он использует его, если нет, он использует пользовательскую функцию.

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

Синан
источник
1
Имейте в виду, что полифилл работает только с числами, которые имеют не более 3 десятичных знаков. Например, 0.12345будет выводить 0.12,345. Хорошая реализация для этого может быть найдена в underscore.string
Энди
вы правы, value > 1000если условие if исправит этот случай, однако это был случай, и, конечно, лучше протестированные версии можно найти в другом месте, спасибо за указание.
Синан
1
Недостаточно поставить value > 1000, потому что он будет одинаковым для любого числа и более 3 десятичных знаков. например, 1000.12345возвращается 1,000.12,345. Ваш ответ отличный и на правильном пути, но просто не полный. Я только пытался указать на других людей, которые могут наткнуться на ваш ответ и просто скопировать / вставить его, не тестируя с другими входными данными.
Энди
1
ладно, это нужно было еще раз отредактировать :) Я согласен, но теперь по крайней мере это должно работать для большинства случаев.
Синан
18

Разделитель тысяч может быть вставлен в дружественном для международного сообщества виде с помощью Intlобъекта браузера :

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

См. Статью MDN о NumberFormat , где вы можете указать поведение локали или значение по умолчанию для пользователя. Это немного более надежно, потому что учитывает местные различия; во многих странах для разделения цифр используются точки, а запятая обозначает десятичные дроби.

Intl.NumberFormat доступен не во всех браузерах, но работает в последних версиях Chrome, Opera и IE. Следующий релиз Firefox должен его поддерживать. У Webkit, похоже, нет графика реализации.

phette23
источник
2
Хотя это было бы замечательно, если бы мы могли использовать простую встроенную функцию, у нее ужасная реализация в браузере. Например, IE 8-10 и все Safari не поддерживают это
Блейн Кастен
@BlaineKasten есть полностью совместимый polyfill для старых браузеров, доступный здесь: github.com/andyearnshaw/Intl.js, он огромный, но работает.
Mahn
1
Доступно через CDN pollyfill (возвращает только то, что нужно на основе идентификатора пользователя): cdn.polyfill.io/v2/polyfill.min.js?features=Intl
Кевин,
Были проблемы с форматированием больших чисел с помощью toLocaleString, это отлично работало (с polyfill)
ask_io
18

Вы можете использовать эту процедуру для форматирования нужной вам валюты.

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

Для получения дополнительной информации вы можете получить доступ к этой ссылке.

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

Дулит Де Коста
источник
Это правильный, портативный, родной ответ. Хотелось бы, чтобы я проголосовал не раз.
Джаред Смит
14

если вы работаете с валютными значениями и много форматируете, то, возможно, стоит добавить крошечный accounting.js, который обрабатывает множество крайних случаев и локализацию:

// 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
Шиталь шах
источник
1
Ссылка больше не работает. Но выглядит примерно так: openexchangerates.github.io/accounting.js
ush189
13

Следующий код использует сканирование символов, поэтому здесь нет регулярных выражений.

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] : ''); 
}

Это показывает многообещающую производительность: http://jsperf.com/number-formatting-with-commas/5

2015.4.26: Незначительное исправление для устранения проблемы при num <0. Смотрите https://jsfiddle.net/runsun/p5tqqvs3/

runsun
источник
это не работает с commafy(-123456)этим дает-,123,456
wrossmck
Это замечательно! Спасибо за то, что собрали jsperf
fregante
Этот фрагмент - абсолютный монстр, он выполняет все.
NiCk Ньюман
13

Вот простая функция, которая вставляет запятые для тысяч разделителей. Он использует функции массива, а не RegEx.

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

Ссылка CodeSandbox с примерами: https://codesandbox.io/s/p38k63w0vq

Ной Фрейтас
источник
1
Привет .. Этот пример отличный. Но это будет ставить запятые и для десятичной части. просто редактирование: функция formatNumber (num) {var decimalPart = ''; num = num.toString (); if (num.indexOf ('.')! = -1) {decimalPart = '.' + num.split ('.') [1]; num = parseInt (num.split ('.') [0]); } var array = num.toString (). split (''); индекс var = -3; while (array.length + index> 0) {array.splice (index, 0, ','); // Уменьшение на 4, так как мы просто добавили еще один модуль в массив. индекс - = 4; } return array.join ('') + decimalPart; };
Aki143S
Спасибо, сэр. Это именно то, что мне было нужно.
Амир Хоссейн Ахмади
11

Используйте этот код для обработки формата валюты для Индии. Код страны может быть изменен для обработки другой валюты страны.

let amount =350256.95
var formatter = new Intl.NumberFormat('en-IN', {
  minimumFractionDigits: 2,
});

// Use it.

formatter.format(amount);

вывод:

3,50,256.95
Батри Натан
источник
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и / или почему он решает проблему, улучшит долгосрочную ценность ответа. Прочитайте это .
Шантешвар Инд
@ShanteshwarInde Я добавлю дополнительный контекст, чтобы улучшить ответ наверняка
Батри Натан
11

Вы также можете использовать конструктор Intl.NumberFormat . Вот как вы можете это сделать.

 resultNumber = new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(yourNumber); 
Оливер
источник
это не рабочий узел JS. Это не дает ответ в индийском формате
Сурадж Далви
7

Я написал это, прежде чем наткнуться на этот пост. Нет регулярных выражений, и вы действительно можете понять код.

$(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>

Ронни Оверби
источник
1
Я добавил s.toString () в начале функции, чтобы она тоже могла принимать числа, а не только строки. Это мой предпочтительный ответ, потому что он читабелен, лаконичен и не содержит ошибок, которые, как кажется, есть в регулярных выражениях.
FeFiFoFu
7
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(".");
}

РЕДАКТИРОВАТЬ: функция работает только с положительным числом. для примера:

var number = -123123231232;
formatNumber(number)

Выход: "123,123,231,232"

Но для ответа на вопрос выше toLocaleString()метод просто решает проблему.

var number = 123123231232;
    number.toLocaleString()

Выход: "123,123,231,232"

Не унывайте!

Кири Ме
источник
1
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и / или почему он решает проблему, улучшит долгосрочную ценность ответа.
Дональд Дак
1
Хороший скрипт, но он не работает с отрицательными числами.
Ральф Дэвид Абернати
7

Мой ответ - единственный ответ, который полностью заменяет jQuery гораздо более разумной альтернативой:

function $(dollarAmount)
{
    const locale = 'en-US';
    const options = { style: 'currency', currency: 'USD' };
    return Intl.NumberFormat(locale, options).format(dollarAmount);
}

Это решение не только добавляет запятые, но и округляет до ближайшей копейки, если вы $(1000.9999)введете сумму, равную 1 001,00 долл. США. Кроме того, введенное вами значение может безопасно представлять собой число или строку; это не важно

Если вы имеете дело с деньгами, но не хотите, чтобы на сумме отображался ведущий знак доллара, вы также можете добавить эту функцию, которая использует предыдущую функцию, но удаляет $:

function no$(dollarAmount)
{
    return $(dollarAmount).replace('$','');
}

Если вы не имеете дело с деньгами и предъявляете различные требования к десятичному форматированию, вот более универсальная функция:

function addCommas(number, minDecimalPlaces = 0, maxDecimalPlaces = Math.max(3,minDecimalPlaces))
{
    const options = {};
    options.maximumFractionDigits = maxDecimalPlaces;
    options.minimumFractionDigits = minDecimalPlaces;
    return Intl.NumberFormat('en-US',options).format(number);
}

Да, и, кстати, тот факт, что этот код не работает в какой-то старой версии Internet Explorer, является полностью преднамеренным. Я пытаюсь сломать IE в любое время, когда я могу его поймать, не поддерживая современные стандарты.

Пожалуйста, помните, что чрезмерная похвала в разделе комментариев считается не по теме. Вместо этого просто засыпайте меня голосами "за".

Лонни Бест
источник
1
Number (n) .toLocaleString () кажется лучшим ответом, но вы, вероятно, захотите использовать что-то вроде нового Intl.NumberFormat ('en-US'). Format (n) вместо удаления знаков доллара и десятичных дробей, если все пользователь хочет запятые в их числе.
bmacnaughton
@bmacnaughton: Это хороший момент, когда вы не имеете дело с деньгами. Однако, если вы имеете дело с деньгами и просто «не хотите использовать ведущий знак доллара», Number (1000.50) .toLocaleString () выдает «1,000,5», что удаляет незначительный ноль, который обычно сохраняется при отображении значений денег. Хороший комментарий: все должны знать, что вы сказали.
Лонни Бест
6

Для меня лучший ответ - использовать toLocaleString, как говорили некоторые участники. Если вы хотите включить символ '$', просто добавьте язык и введите параметры. Вот и пример форматирования номера в мексиканские песо

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

сокращенный

1234567.22.toLocaleString("es-MX",{style:"currency", currency:"MXN"})
Карлос А. Ортиз
источник
5

Позвольте мне попытаться улучшить uKolka «s ответа и , возможно , помочь другим сэкономить некоторое время.

Используйте Numeral.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>

Вы должны использовать Number.prototype.toLocaleString (), только если его совместимость с браузером не является проблемой.

Бедер Акоста Борхес
источник
это вдохновило меня на npm установить цифру
steampowered
5

Альтернативный способ, поддержка десятичных знаков, различных разделителей и негативов.

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.floor(Math.abs(number)).toString()

        , i     = n.length % 3 
        , f     = ((number < 0) ? '-' : '') + n.substr(0, i)
    ;

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

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

    return f;
}

Некоторые исправления @Jignesh Sanghani, не забудьте высказать свой комментарий.

Фелипе Буччони
источник
Идеально для меня, просто добавили новую строку для удаления форматирования перед обработкой.
Деннис Хайден
2
fn.substr(0, i)заменить на, n.substr(0, i)а также number.toFixed(dp).split('.')[1]заменить на parseFloat(number).toFixed(dp).split('.')[1]. потому что, когда я использую напрямую, это дает мне ошибку. пожалуйста, обновите свой код
Jignesh Sanghani
недостатки. число растет. вызов экзамена был бы великолепен!
ммм
переключение ceil на пол исправлено, но не уверен, какие другие проблемы возникнут.
ммм
1
Попробуйте Math.floor (-75,1);)
ммм
4

Я думаю, что эта функция позаботится обо всех проблемах, связанных с этой проблемой.

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;
}
AbhinavRanjan
источник
4

Просто для будущих Googlers (или не обязательно «Googlers»):

Все решения, упомянутые выше, замечательны, однако RegExp может быть ужасно плохой вещью в такой ситуации.

Итак, да, вы можете использовать некоторые из предложенных вариантов или даже написать что-нибудь примитивное, но полезное, например:

const strToNum = str => {

   //Find 1-3 digits followed by exactly 3 digits & a comma or end of string
   let regx = /(\d{1,3})(\d{3}(?:,|$))/;
   let currStr;

   do {
       currStr = (currStr || str.split(`.`)[0])
           .replace( regx, `$1,$2`)
   } while (currStr.match(regx)) //Stop when there's no match & null's returned

   return ( str.split(`.`)[1] ) ?
           currStr.concat(`.`, str.split(`.`)[1]) :
           currStr;

};

strToNum(`123`) // => 123
strToNum(`123456`) // => 123,456
strToNum(`-1234567.0987`) // => -1,234,567.0987

Используемое здесь регулярное выражение довольно простое, и цикл будет идти ровно столько раз, сколько потребуется для выполнения работы.

И вы могли бы оптимизировать его гораздо лучше, код «DRYify» и так далее.

Еще,

(-1234567.0987).toLocaleString();

(в большинстве ситуаций) будет гораздо лучшим выбором.

Дело не в скорости исполнения и не в кросс-браузерной совместимости.

В ситуациях, когда вы хотите показать полученное число пользователю, метод .toLocaleString () дает вам сверхспособность говорить на одном языке с пользователем вашего веб-сайта или приложения (независимо от того, какой у него язык).

Этот метод в соответствии с документацией ECMAScript был введен в 1999 году, и я считаю, что причиной этого была надежда, что Интернет в какой-то момент соединит людей во всем мире, поэтому потребовались некоторые инструменты «интернализации».

Сегодня Интернет связывает нас всех, поэтому важно помнить, что мир намного сложнее, чем мы можем себе представить, и (/ почти) все мы здесь , в Интернете.

Очевидно, что, учитывая разнообразие людей, невозможно гарантировать идеальный UX для всех, потому что мы говорим на разных языках, ценим разные вещи и т. Д. И именно из-за этого еще более важно попытаться локализовать вещи настолько, насколько это возможно. ,

Итак, учитывая, что существуют определенные стандарты для представления даты, времени, чисел и т. Д. И что у нас есть инструмент для отображения этих вещей в формате, предпочитаемом конечным пользователем, это не так уж редко и почти безответственно использовать этот инструмент (особенно в ситуациях, когда мы хотим показать эти данные пользователю)?

Для меня использование RegExp вместо .toLocaleString () в подобной ситуации звучит немного похоже на создание приложения для часов с JavaScript и его жесткое программирование таким образом, чтобы оно отображало только пражское время (что было бы совершенно бесполезно для люди, которые не живут в Праге), хотя поведение по умолчанию

new Date();

вернуть данные в соответствии с конечными часами пользователя.

Игорь Быков
источник
почему вы написали функцию с const и =>?
О. Г. Шон
@OGSean Я всегда так делаю, так как это самый удобный способ объявления переменных и функций. Кроме того, я думаю, что это помогает сохранить код чище и короче.
Игорь Быков
4

Мое « истинное » решение только для регулярных выражений для тех, кто любит однострочники

Вы видите тех восторженных игроков выше? Может быть, вы можете играть в гольф из этого. Вот мой инсульт.

n => `${n}`.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " ").replace(/(?<=\.(\d{3})+)\B/g, " ")

Использует ТОНКОЕ ПРОСТРАНСТВО (U + 2009) для разделителя тысяч, как сказано в Международной системе единиц в восьмом издании (2006 г.) их публикации « Брошюра СИ: Международная система единиц (СИ) » (см. §5.3 0,4.). Девятое издание (2019) предлагает использовать пространство для него (См §5.4.4.). Вы можете использовать все, что хотите, включая запятую.


Видеть.

const integer_part_only = n => `${n}`.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " I ");
const fractional_part_only = n => `${n}`.replace(/(?<=\.(\d{3})+)\B/g, " F ");
const both = n => fractional_part_only(integer_part_only(n));

function demo(number) { // I’m using Chrome 74.
	console.log(`${number}
		 "${integer_part_only(number)}" (integer part only)
		 "${fractional_part_only(number)}" (fractional part only)
		 "${both(number)}" (both)
	`);
}
demo(Math.random() * 10e5);
demo(123456789.01234567);
demo(123456789);
demo(0.0123456789);


Как это работает?

Для целой части

.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, " I ")
  • .replace(……, " I ") Поставить «я»
    • /……/g на каждом из
      • \B между двумя соседними цифрами
        • (?=……)ПОЗИТИВНО LOOKAHEAD , правая часть которого
          • (\d{3})+ один или несколько трехзначных блоков
          • \b за которым следует нецифровка, такая как точка, конец строки и т. д.,
        • (?<!……)ОТРИЦАТЕЛЬНЫЙ СМОТРЕТЬ исключая тех, чья левая часть
          • \.\d+ является точкой, за которой следуют цифры («имеет десятичный разделитель»).

Для десятичной части

.replace(/(?<=\.(\d{3})+)\B/g, " F ")
  • .replace(……, " F ") Поставить «F»
    • /……/g на каждом из
      • \B между двумя соседними цифрами
        • (?<=……)ПОЗИТИВНО СМОТРЕТЬ, чья левая часть
          • \. десятичный разделитель
          • (\d{3})+ сопровождаемый одним или несколькими кусками с тремя цифрами.

Классы персонажей и границы

\d

Соответствует любой цифре (арабская цифра). Эквивалент [0-9].

Например,

  • /\d/или /[0-9]/спички 2в B2 is the suite number.

\b

Соответствует границе слова . Это позиция, где за символом слова не следует или не предшествует другой символ слова, например между буквой и пробелом. Обратите внимание, что соответствующая граница слова не включена в соответствие. Другими словами, длина совпадающей границы слова равна нулю.

Примеры:

  • /\bm/соответствует mв moon;
  • /oo\b/не соответствует ooin moon, потому что ooза nкоторым следует слово символа;
  • /oon\b/соответствует oonin moon, потому что oonэто конец строки, поэтому за ним не следует символ слова;
  • /\w\b\w/ никогда не будет соответствовать чему-либо, потому что за символом слова не может следовать ни слово, ни слово.

\B

Соответствует границе без слова . Это позиция, в которой предыдущий и следующий символ имеют одинаковый тип: либо оба должны быть словами, либо оба должны быть не словами. Например, между двумя буквами или между двумя пробелами. Начало и конец строки считаются не словами. То же самое, что и совпадающая граница слова, совпадающая граница не из слов также не включается в совпадение.

Например,

  • /\Bon/совпадения onв at noon;
  • /ye\B/матчи yeв possibly yesterday.

Совместимость браузера

Константин Ван
источник
3

Я добавил Tofixed к решению Aki143S . Это решение использует точки для тысяч разделителей и запятую для точности.

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

Примеры;

formatNumber(17347, 0)  = 17.347
formatNumber(17347, 3)  = 17.347,000
formatNumber(1234563.4545, 3)  = 1.234.563,454
bartburkhardt
источник
3

Я думаю, что ваше решение является одним из самых коротких, которые я видел для этого. Я не думаю, что есть какие-то стандартные функции JavaScript, чтобы делать такие вещи, так что вы, вероятно, самостоятельно.

Я проверил спецификации CSS 3, чтобы увидеть, возможно ли это сделать в CSS, но если вы не хотите, чтобы каждая цифра была отдельной <span>, я не думаю, что это возможно.

Я нашел один проект в Google Code, который выглядел многообещающе: Flexible-JS-форматирование . Я не использовал его, но он выглядит довольно гибким и имеет модульные тесты с использованием JsUnit . У разработчика также есть много постов (хотя и старых) на эту тему.

Обязательно учитывайте международных пользователей: многие страны используют пробел в качестве разделителя и используют запятую для отделения десятичной дроби от целой части числа.

jasonmp85
источник
Не могли бы вы опубликовать решение с использованием только CSS и охватывает?
Крис Бетти