Разделитель тысяч / строковый формат Javascript [дубликат]

101

Есть ли в Javascript какая-либо функция для форматирования чисел и строк?

Я ищу способ разделителя тысяч для строки или чисел ... (например, String.Format в С #)

LostLord
источник
Думаю, вы найдете там то, что вам нужно :) stackoverflow.com/questions/610406/…
Джад
How to print a number with commas as thousands separators in JavaScript: stackoverflow.com/questions/2901102/…
Адриан Бе

Ответы:

172

Обновление (7 лет спустя)

Ссылка, указанная в исходном ответе ниже, была неправильной. Для этого есть встроенная функция, которую Кайзер предлагает ниже:toLocaleString

Итак, вы можете:

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

Реализованная ниже функция тоже работает, но в этом нет необходимости.

(Я подумал, что, возможно, мне повезет, и я узнаю, что это было необходимо еще в 2010 году, но нет. Согласно этой более надежной ссылке , toLocaleString является частью стандарта с ECMAScript 3rd Edition [1999], что, как мне кажется, означает поддерживался бы еще в IE 5.5.)


Оригинальный ответ

Согласно этой ссылке нет встроенной функции для добавления запятых к числу. Но на этой странице есть пример того, как это написать самостоятельно:

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

Изменить: чтобы пойти другим путем (преобразовать строку с запятыми в число), вы можете сделать что-то вроде этого:

parseFloat("1,234,567.89".replace(/,/g,''))
Тим Гудман
источник
1
Действительно действительно ценить это // Но как я могу преобразовать эту строку (с запятыми) в число?
LostLord
эта функция не работает для чисел больше 100 000
DevZer0
1
@ DevZer0 нет, это не так
Tallboy
работает с чистым javascript + одно регулярное выражение заменить stackoverflow.com/a/44324879/681830
Val
4
использовать (1234567).toLocaleString().replace(/,/g," ",)для пробелов между тысячами
Fanky
123

Если речь идет о локализации разделителей тысяч, разделителей и десятичных разделителей, выполните следующие действия:

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

Есть несколько вариантов, которые вы можете использовать (и даже языковые стандарты с запасными вариантами):

number = 123456.7089;

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

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

Подробности на информационной странице MDN .

Edit: Commentor @I как Серена добавляет следующее:

Для поддержки браузеров с неанглийской локалью, где нам все еще требуется английское форматирование, используйте value.toLocaleString('en'). Также работает с плавающей точкой.

кайзер
источник
Это не относится к числам с плавающей запятой .. вы можете изменить parseInt на parseFloat, но если yourInt = "100,12" (запятая как десятичный разделитель), это не удастся. Это можно исправить с помощью replace (",", ".") .. но снова не удастся с "1.000,12". Итак ... Иногда вам НЕОБХОДИМО изобретать велосипед. stackoverflow.com/a/2901298/1028304
Neiker
1
Это было бы более подходящим:Number(yourNumberOrString).toLocaleString()
Джонатан
2
Для поддержки браузеров с неанглийской локалью, где нам все еще требуется английское форматирование, используйте value.toLocaleString('en'). Также работает с плавающей точкой.
Клаас ван Аарсен,
1
@ Serhiog.Lazin Что именно не работает в Safari (и на какой ОС и в какой версии)?
kaiser
1
К вашему сведению, для формата чисел Индии, например 7,77,77,777, используйтеvalue.toLocaleString('en-IN')
Макеш
37

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

Можно использовать регулярное выражение, что особенно полезно при работе с большими числами, хранящимися в виде строк.

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

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

»Подробное объяснение регулярного выражения (regex101.com) схема потока


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

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

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

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

» Verbose regex explanation (regex101.com)

flow diagram

Emissary
источник
Has this syntax diagram been created on regex101.com?
Gerold Broser
what happen with numbers with decimals?
Emiliano
I'm getting "Invalid regular expression: invalid group specifier name". On React Native 0.59 doing this but that really shouldn't affect RegEx.
Joshua Pinter
@JoshuaPinter It'll be the use of look-behind which at time of writing is not yet supported across all platforms. I'm guessing you're referring specifically to iOS - as Safari still fails for me too. It may be best to stick with the backward compatible version for now. I was just trying to future-proof my answer. caniuse.com/#search=lookbehind
Emissary
1
@Emissary Thanks for the tip. Yeah, it's on React Native 0.59 / Android, which uses a relatively older version of JavaScriptCore (JSC). I'll try again after we update to React Native 0.60+, which includes an update to the JSC.
Joshua Pinter
11

There's a nice jQuery number plugin: https://github.com/teamdf/jquery-number

It allows you to change any number in the format you like, with options for decimal digits and separator characters for decimal and thousand:

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

You can use it inside input fields directly, which is nicer, using same options like above:

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

Or you can apply to a whole set of DOM elements using selector:

$('span.number').number(true, 2);
qdev
источник
best solution imho
Michal
I don't think so, adding a new file requirement with almost 800 lines , it is like kill an ant with a granade
Emiliano
6

I use this:

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

source: link

Abhishek Goel
источник
'123452343267.0505'.replace(/\B(?=(\d{3})+(?!\d))/g, ","); "123,452,343,267.0,505" - notice that last comma after the decimal point.
hippietrail
5
// thousand separates a digit-only string using commas
// by element:  onkeyup = "ThousandSeparate(this)"
// by ID:       onkeyup = "ThousandSeparate('txt1','lbl1')"
function ThousandSeparate()
{
    if (arguments.length == 1)
    {
        var V = arguments[0].value;
        V = V.replace(/,/g,'');
        var R = new RegExp('(-?[0-9]+)([0-9]{3})'); 
        while(R.test(V))
        {
            V = V.replace(R, '$1,$2');
        }
        arguments[0].value = V;
    }
    else  if ( arguments.length == 2)
    {
        var V = document.getElementById(arguments[0]).value;
        var R = new RegExp('(-?[0-9]+)([0-9]{3})'); 
        while(R.test(V))
        {
            V = V.replace(R, '$1,$2');
        }
        document.getElementById(arguments[1]).innerHTML = V;
    }
    else return false;
}   
h.foroutan
источник
3

You can use javascript. below are the code, it will only accept numeric and one dot

here is the javascript

<script >

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

                var val = ctrl.value;

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

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

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

                ctrl.value = x1 + x2;
            }

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

  </script>

HTML

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

DEMO JSFIDDLE

Awtszs
источник
2
number = 123456.7089;
result = parseInt( number ).toLocaleString() + "<br>";
result = number.toLocaleString( 'pt-BR' ) + "<br>";

var el = document.getElementById( 'result' );
el.innerHTML = result;
<div id="result"></div>
Ricardo
источник
6
Can you please add some description as well so that op and other people can understand that how this code actually solve the problem. Thanks
Punit Gajjar
try with a nomber beteen 1000 and 9999
Emiliano
1

All you need to do is just really this:

123000.9123.toLocaleString()
//result will be "123,000.912"
Ezeewei
источник
Unfortunately it depends on your platform. Some have a toLocaleString() which does not add the commas, or lacks other features in the standard. It's easy to check for toLocaleString presence but not to check for its compliance.
hippietrail
try with a number between 1000 and 9999
Emiliano
0

Combination of solutions for react

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

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

handleOnChangeMonthlySalary(1000)```
Chinedu Ofor
источник
0

You can use ngx-format-field. It is a directive to format the input value which will appear in the view. It will not manipulate the Input value which will be saved in the backend. See link here!

Example:

component.html:

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

component.ts

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

To see the demo: here!

moumita kundu
источник
0

You can use the following function:

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

// Use Example

let min = 1556454.0001;
let max = 15556982.9999;

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

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

jin_maxtor
источник
Don't make it so confusing. just use toLocaleString(). More information in developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Sajad Saderi
@sajadsaderi I also use toLocaleString () friend, but this function doesn't give me much flexibility, so I don't have to be dealing with regional abbreviations and someone else could use it since the definition of this function is identical to the number_format () function of php.
jin_maxtor
-1

I did not like any of the answers here, so I created a function that worked for me. Just want to share in case anyone else finds it useful.

function getFormattedCurrency(num) {
    num = num.toFixed(2)
    var cents = (num - Math.floor(num)).toFixed(2);
    return Math.floor(num).toLocaleString() + '.' + cents.split('.')[1];
}
Spencer Sullivan
источник