webdevqa.jp.net

JavaScriptで桁区切り記号としてカンマ付きの数字を印刷する方法

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

それを行うためのより簡単な、またはよりエレガントな方法はありますか?フロートでもうまく動作すればいいのですが、それは必須ではありません。ピリオドとコンマの間で決定するためにロケール固有である必要はありません。

1404
Elias Zamaria

私はケリーの答えからのアイデアを使用しましたが、私は私の特定の目的のために単純な何かを探していたのでそれを単純化しました。これが私がしたことです:

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

これはあなたが本当に知る必要があるすべてです。

@Neils Bomは、正規表現のしくみを尋ねました。私の説明は少し長いです。それはコメントに収まりません、そして、私はここでそれをしているので、私は他にそれをどこに置くべきかわかりません。それをどこに置くかについて他の提案があるならば、私に知らせてください。

正規表現では2つの先読みアサーションが使用されます。文字列内の3桁の倍数がある行を検索するための正のアサーションと、その桁が3桁の倍数のみであることを確認するための負のアサーションです。置換式は、そこにコンマを置きます。

たとえば、 "123456789.01"を渡すと、ポジティブアサーションは7の左側のすべてのスポットに一致します( "789"は3桁の倍数であるため、 "678"は3桁の倍数 "567"、等。)。否定アサーションは、3桁の倍数にその後に数字がないことを確認します。 "789"の後にはピリオドがあるので、正確には3桁の倍数であるため、そこにコンマが入ります。 「678」は3桁の倍数ですが、その後に「9」が付きます。したがって、これらの3桁は4のグループの一部であり、カンマはそこに入りません。 "567"についても同様です。 "456789"は6桁で、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(".");
}
2383
Elias Zamaria

Number.prototype.toLocaleString 。誰も言及していないのに驚いた。 1999年に導入されたJavaScript 1.5で実装されているので、基本的にすべての主要ブラウザでサポートされています。

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

Intl を含めることでv0.12以降のNode.jsでも動作します。

この関数が数値ではなく文字列を返すことに注意してください。

何か違うものが欲しいなら、 Numeral.js が面白いかもしれません。

1358
uKolka
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"


NumberFormatSafariはサポートされていません):

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

私が調べたところ(少なくともFirefox)、パフォーマンスに関してはどちらもほぼ同じです。

202
vsync

Phpjs.orgの 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

人々はこれが期待通りに動かないと報告していたので、私は自動テストを含む 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;
}
98
Kerry Jones

これは@ mikez302の答えの変形ですが、小数点以下の桁数をサポートするように変更されました(@ neu-rahのフィードバックによると、numberWithCommas(12345.6789) - > "12,345.6789"ではなく "12,345.6789")。

function numberWithCommas(n) {
    var parts=n.toString().split(".");
    return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + (parts[1] ? "." + parts[1] : "");
}
67
user1437663
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
58
Tutankhamen

正規表現を使用する

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

デモATこちら

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

パフォーマンス

Performance http://jsben.ch/sifRd

45
TinhNQ

Intl.NumberFormat

ネイティブJS関数IE11、Edge、最新のSafari、Chrome、Firefox、Opera、iOSのSafari、AndroidのChromeでサポートされています。

var number = 3500;

console.log(new Intl.NumberFormat().format(number));
// → '3,500' if in US English locale
34
lonelyloner

回答いただきありがとうございます。私はいくつかの答えをもとにして、より「万能」の解決策を作りました。

最初のスニペットは、 _ php _number_format()を模した関数をNumberプロトタイプに追加します。私が数をフォーマットしているなら、私は通常小数点以下の桁数が欲しいので関数は表示するために小数点以下の桁数を取ります。国によっては、小数点としてコンマを使用し、桁区切りとして小数点を使用するため、これらの区切り文字を設定できます。

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は単に整数値の最初のシーケンスを使って5,000から5に変換します。そこで私は自分自身のfloat型変換関数を作成し、それを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
32
J.Money

私はこれがそれをする最短の正規表現だと思います:

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

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

私はいくつかの数字でそれをチェックし、そしてそれはうまくいった。

21
user3664916

すべてのブラウザでネイティブに提供されているのであればNumber.prototype.toLocaleString()はすごかったでしょう (Safari)

私は他のすべての答えをチェックしましたが、誰もそれを満たすことはできませんでした。これは、実際に最初の2つの答えを組み合わせたものです。 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));
18
Sinan

千単位の区切り記号は、ブラウザの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には実装の予定はありません。

16
phette23

この手順を使用して、必要な通貨をフォーマットできます。

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

15
Dulith De Costa

あなたが通貨の値を扱っていてたくさんフォーマットしているのであれば、小さな 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
13
Shital Shah

次のコードは文字スキャンを使用しているので、正規表現はありません。

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/ を参照してください。

12
runsun

これは、千の区切り文字にカンマを挿入する簡単な関数です。 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

9
Noah Freitas

私はこの記事につまずく前にこれを書いた。正規表現がなくても、実際にコードを理解できます。

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

私にとって、最良の答えは、何人かのメンバーが言ったようにtoLocaleStringを使うことです。あなたが '$'記号を含めたいのならば、ちょうどinflaajeとタイプオプションを追加してください。メキシコペソに数値をフォーマットするためのこれと例はここにあります

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

ショートカット

1234567.22.toLocaleString("es-MX",{style:"currency", currency:"MXN"})
6
Carlos A. Ortiz

Intl.NumberFormat コンストラクターを使用することもできます。方法は次のとおりです。

 resultNumber = new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(yourNumber); 
5
Oliver
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"

応援します。

5
Kiry Meas

このコードを使用してインドの通貨フォーマットを処理します。国コードは他の国の通貨を扱うために変更することができます。

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

// Use it.

formatter.format(amount);

出力:

3,50,256.95
5
Bathri Nathan

uKolkaanswer を改善してみてください。

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() を指定してください。

5

この機能は、この問題に関連するすべての問題を処理すると思います。

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
AbhinavRanjan

Aki143S のソリューションにtofixedを追加しました。このソリューションでは、千単位の区切り記号にドットを使用し、精度にコンマを使用しています。

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

すでにたくさんの良い答えがあります。もう1つ、楽しみのために:

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

いくつかの例:

format(77.03453, 2); // "77.03"
format(78436589374); // "78,436,589,374"
format(784, 4);      // "784.0000"
format(-123456);     // "-123,456"
3
Wayne Burkett

私はあなたの解決策が私がこれのために見たより短いもののうちの1つであると思います。私はこの種のことをするための標準的なJavaScript関数があるとは思わないので、あなたはおそらくあなた自身の上にいるでしょう。

CSS 3の仕様を調べてCSSでこれが可能かどうかを確認しましたが、すべての桁を独自の<span>で指定しない限り、それは不可能だと思います。

Google Code で有望に見えるプロジェクトが1つ見つかりました: flexible-js-format 。まだ使っていませんが、かなり柔軟に見え、 JsUnit を使った単体テストがあります。開発者は、このトピックに関するたくさんの投稿を(古いですが)持っています。

国際的なユーザーを考慮する必要があります。多くの国では区切り文字としてスペースを使用し、数値の整数部分から小数点を区切るためにコンマを使用します。

2
jasonmp85

Mytrue正規表現のみのソリューション ワンライナーを愛する人のために

あなたは上記の熱狂的なプレーヤーを見ますか?たぶんあなたはそれからゴルフをすることができます。これが私のストロークです。

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

を使用します薄いスペース (U + 2009)国際単位系第8版(2006) 彼らの出版物「SI Brochure:The International System of Units(SI) (§5.3.4。を参照)。 第9版(2019) は、spaceを使用することを提案します(§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 ")「I」を入れます
    • /……/g
      • \B 2つの隣接する数字の中間
        • (?=……)ポジティブルーカヘッド 右の部分は
          • (\d{3})+ 1つ以上の3桁のチャンク
          • \bの後にピリオド、文字列の終わりなどの非数字が続きます。
        • (?<!……)ネガティブルックビハインド 左部分を持つものを除く
          • \.\d+は、ドットの後に数字が続きます(「小数点があります」)。

小数部の場合

.replace(/(?<=\.(\d{3})+)\B/g, " F ")
  • .replace(……, " F ")「F」を入れる
    • /……/g
      • \B 2つの隣接する数字の中間
        • (?<=……)ポジティブルックビハインド 左の部分は
          • \.小数点記号
          • (\d{3})+の後に1つ以上の3桁のチャンクが続きます。

文字クラス および 境界

\d

任意の数字(アラビア数字)に一致します。 [0-9]と同等。

例えば、

  • /\d/または/[0-9]/は、2B2 is the suite numberと一致します。

\b

単語境界に一致します。これは、文字とスペースの間など、Word文字の後に別のWord文字が続くまたは先行しない位置です。一致したWord境界は一致に含まれないことに注意してください。つまり、一致したWord境界の長さはゼロです。

例:

  • /\bm/は、mmoonと一致します。
  • ooの後にmoonが続くため、/oo\b/oonと一致しません。
  • /oon\b/は、oonmoonと一致します。これは、oonが文字列の終わりであり、したがってWord文字が続かないためです。
  • /\w\b\w/は、Wordの文字の後に非WordとWordの文字の両方が続くことはないため、何にも一致しません。

\B

非単語境界に一致します。これは、前の文字と次の文字が同じタイプの位置です。どちらも単語でなければならないか、両方とも単語以外でなければなりません。 2つの文字間または2つのスペース間など。文字列の先頭と末尾は非単語と見なされます。一致した単語の境界と同じですが、一致した非単語の境界も一致に含まれません。

例えば、

  • /\Bon/at noononと一致します。
  • /ye\B/は、possibly yesterdayyeと一致します。

ブラウザの互換性

@ user1437663からの解決策は素晴らしいです。

その解決策を本当に理解している人は、複雑な正規表現を理解する準備ができています。

読みやすくするための小さな改善

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

Wordの先頭にカンマを使用しないようにするため、パターンは \B で始まります。興味深いことに、 \B は "カーソル"を進めないため、パターンは空になります( $ にも同じことが当てはまります)。

O \B の後にはあまり知られていないリソースが続きますが、Perlの正規表現からの強力な機能です。

            Pattern1 (? = (Pattern2) ).

括弧の中にあるもの( Pattern2 )は前のパターン( Pattern1 )に続くパターンですが、カーソルを進めずに返されるパターンの一部ではないということです。それは一種の未来のパターンです。これは、誰かが前を向いていても実際には歩いていないときに似ています。

この場合、 パターン2

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

これは、3桁(1回以上)の後にストリングの終わり($)が続くことを意味します。

最後に、 Replace methodは、見つかったパターン(空の文字列)のすべての出現箇所をコンマで変更します。これは、残りの部分が3桁の倍数である場合(将来のカーソルが原点の端に達するような場合)にのみ発生します。

2
Paulo Buchsbaum

これはintとdecimalをサポートする1​​行の関数です。数字を文字列に変換するためのコードもいくつか残しました。

    function numberWithCommas(x) {
        return (x=x+'').replace(new RegExp('\\B(?=(\\d{3})+'+(~x.indexOf('.')?'\\.':'$')+')','g'),',');
    }
1
arosolino

これが私の試みです:

編集:小数で追加

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)
1
Matt Scheurich

小数点、異なる区切り文字、およびマイナスをサポートする別の方法。

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     = ((number < 0) ? '-' : '') + fn.substr(0, i)
    ;

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

あらゆる状況で機能するアプローチを見つけました。 CodeSandboxの例

function commas(n) {
  if (n < 1000) {
    return n + ''
  } else {
    // Convert to string.
    n += ''

    // Skip scientific notation.
    if (n.indexOf('e') !== -1) {
      return n
    }

    // Support fractions.
    let i = n.indexOf('.')
    let f = i == -1 ? '' : n.slice(i)
    if (f) n = n.slice(0, i)

    // Add commas.
    i = n.length
    n = n.split('')
    while (i > 3) n.splice((i -= 3), 0, ',')
    return n.join('') + f
  }
}

これは Noah Freitasの答え のようですが、 fraction および 科学表記 をサポートしています。

パフォーマンスが問題にならないのであれば、toLocaleStringが最良の選択だと思います。

編集: これは、いくつかの例を含むCodeSandboxです。 https://codesandbox.io/s/zmvxjpj6x

1
aleclarson

将来のグーグラーのためだけに(あるいは必ずしも「グーグラー」とは限らない):

上記の解決策はすべて素晴らしいものですが、そのような状況では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()メソッドを使用すると、Webサイトまたはアプリのユーザーと同じ言語で話すことができます(自分の言語が何であれ)。

ECMAScript文書によるこの方法は1999年に導入されました。その理由は、ある時点でインターネットが世界中の人々をつなぐことを願っているため、「内部化」ツールが必要だったと思います。

今日、インターネットは私たち全員をつなげているので、世界は私たちが想像するよりもはるかに複雑なものであること、そして(/ほぼ) 私たちのすべてがここにいる インターネットで。

言うまでもなく、人々の多様性を考えると、私たちは異なる言語を話し、異なるものを重んじるなどして、すべての人にとって完璧なUXを保証することは不可能です。そしてまさにそのため、できる限りローカライズすることが重要です。 。

したがって、日付、時刻、数字などの表現に関する特定の標準があることと、最終ユーザーが好むフォーマットでそれらを表示するためのツールがあることを考えると、それほど珍しくなく、ほとんど無責任ではないそのツールを使用してください(特に、このデータをユーザーに表示したい場合)。

私にとっては、このような状況で.toLocaleString()の代わりにRegExpを使用するのは、JavaScriptで時計アプリを作成し、プラハ時間のみを表示するようにハードコーディングするのとちょっと似ているようです。プラハに住んでいない人は

new Date();

最終ユーザーのクロックに従ってデータを返すことです。

1
Igor Bykov

TextBox(Input type = "text")で動作するようにコードを調整したので、カーソルを失うことなくリアルタイムで数字を入力および削除できます。削除するときに範囲を選択しても機能します。そして、あなたは自由に矢印とホーム/終了ボタンを使うことができます。
私の時間を節約してくれてありがとう!

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

これを使用するには、onKeyUpとonKeyDownの2つのイベントを追加しただけです。

<asp:TextBox runat="server" ID="val" Width="180px" onKeyUp="numberWithCommas(this);" onKeyDown="saveSelectionLength(this);"/>
1
Eluny

あなたがAngularJSを使っているのなら、確かに役立つかもしれないこの通貨フィルタがあります: http://www.w3schools.com/angular/ng_filter_currency.asp

1
Yuxuan Chen

ここで最新の包括的なソリューションを見つけられなかった後、フォーマットの問題を解決するための矢印関数(正規表現なし)を作成しました。これにより、呼び出し元は fraction digit ピリオドと千単位の区切り記号は、ヨーロッパおよびその他の地域用です。

例:

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

ES6 (最新の構文)で記述された関数は次のとおりです。

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

は、否定的な入力、悪い入力、NaNの場合についてテストされています。入力が NaN の場合、単純にそれを返します。

1

次のコードは私のために働きます

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

整数のために私は非常に簡単な方法を使いました:

var myNumber = 99999,
    myString = myNumber + "";

myString.length > 3 ? return myString.substring(0, myString.length - 3) + "," + 
    myString.substring(myString.length - 3) : return myString;
0
Zakhar

インドの数値システム用

var number = "323483.85"
var decimal = number.split(".");
var res = (decimal[0].length>3? numberWithCommas(decimal[0].substring(0,decimal[0].length-3))+ ',' :decimal[0]) + (decimal[0].length>3?decimal[0].substring(decimal[0].length-3,decimal[0].length):'') + '.' + decimal[1];

出力:3,23,483.85

0
Saksham

大量の書式設定に使用している小さなトリックを共有したいと思いました。カンマまたはスペースを挿入する代わりに、私は「千」の間に空だが目に見えるスパンを挿入します。これにより、何千という表示が見やすくなりますが、入力を元の形式でコピー/貼り付けすることができます(カンマ/スペースなし)。

// This function accepts an integer, and produces a piece of HTML that shows it nicely with 
// some empty space at "thousand" markers. 
// Note, these space are not spaces, if you copy paste, they will not be visible.
function valPrettyPrint(orgVal) {
  // Save after-comma text, if present
  var period = orgVal.indexOf(".");
  var frac = period >= 0 ? orgVal.substr(period) : "";
  // Work on input as an integer
  var val = "" + Math.trunc(orgVal);
  var res = "";
  while (val.length > 0) {
    res = val.substr(Math.max(0, val.length - 3), 3) + res;
    val = val.substr(0, val.length - 3);
    if (val.length > 0) {
        res = "<span class='thousandsSeparator'></span>" + res;
    }
  }
  // Add the saved after-period information
  res += frac;
  return res;
}

このCSSでは:

.thousandsSeparator {
  display : inline;
  padding-left : 4px;
}

JSFiddleの例を参照してください。

0
Marcin Zukowski

私の答えは、jQueryをより賢明な代替物に完全に置き換える唯一の答えです。

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

金額の先頭にドル記号を表示したくない場合は、この関数を追加することもできます。この関数は、前の関数を使用しますが、$を削除します。

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

このソリューションは、コンマを追加するだけでなく、$(1000.9999)のような金額を入力した場合に最も近い1セントに切り上げて、$ 1,001.00を取得します。さらに、入力する値は安全に数字または文字列にすることができます。関係ありません。

ああ、ところで、このコードがInternet Explorerの古いバージョンで機能しないという事実は、完全に意図的なものです。私は、現代の標準をサポートしていないことをキャッチできる限り、IEを破ろうとします。

コメントセクションの過度の賞賛は、トピック外と見なされることに注意してください。代わりに、ただ投票してください。

0
Lonnie Best

これは少ないコーディングで良い解決策です...

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 += ",";
}
0
Mosiur