1. ホーム
  2. javascript

[解決済み] JavaScriptでカンマを桁区切りにして数値を表示する方法

2022-03-15 01:43:53

質問

で整数を表示しようとしています。 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;
}

もっとシンプルでエレガントな方法はないのでしょうか?浮動小数点数でも使えるといいのですが、その必要はないでしょう。ピリオドとカンマを区別するために、ロケールに特化する必要はありません。

どのように解決するのですか?

私はKerryさんの回答からアイデアを使いましたが、私の特定の目的のためにシンプルなものを探していたので、簡略化しました。以下は、私が持っているものです。

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

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

function test(x, expect) {
    const result = numberWithCommas(x);
    const pass = result === expect;
    console.log(`${pass ? "✓" : "ERROR ====>"} ${x} => ${result}`);
    return pass;
}

let failures = 0;
failures += !test(0,        "0");
failures += !test(100,      "100");
failures += !test(1000,     "1,000");
failures += !test(10000,    "10,000");
failures += !test(100000,   "100,000");
failures += !test(1000000,  "1,000,000");
failures += !test(10000000, "10,000,000");
if (failures) {
    console.log(`${failures} test(s) failed`);
} else {
    console.log("All tests passed");
}
.as-console-wrapper {
    max-height: 100% !important;
}


正規表現では、2つのルックアヘッド・アサーションを使用しています。

  • 文字列の中で、後ろに3桁の数字が複数並んでいる箇所を探すための正数値のもの。
  • その点がちょうど3桁の倍数であることを確認するための負のアサーション。置換式はそこにカンマを置く。

例えば、これを渡すと 123456789.01 の左側にあるすべての場所にマッチします (なぜなら 789 は3桁の倍数です。 678 は3桁の倍数です。 567 など)。否定的なアサーションは、3桁の倍数がその後に数字を持たないことをチェックする。 789 は後ろにピリオドがあるので、ちょうど3桁の倍数なので、そこにコンマが入ります。 678 は3桁の倍数ですが、その中に 9 ということは、その3桁は4桁のグループの一部であり、そこにコンマは入りません。同様に 567 . 456789 は6桁で、3の倍数なので、その前にコンマが入ります。 345678 は3の倍数ですが、その中に 9 の後なので、コンマは入りません。といった具合です。その \B は、正規表現が文字列の先頭にカンマを置かないようにします。

@ ニューラー は、小数点以下が3桁以上の場合、この関数が好ましくない場所にカンマを追加することを述べています。もし、これが問題であれば、この関数を使用することができます。

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

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

function test(x, expect) {
    const result = numberWithCommas(x);
    const pass = result === expect;
    console.log(`${pass ? "✓" : "ERROR ====>"} ${x} => ${result}`);
    return pass;
}

let failures = 0;
failures += !test(0              , "0");
failures += !test(0.123456       , "0.123456");
failures += !test(100            , "100");
failures += !test(100.123456     , "100.123456");
failures += !test(1000           , "1,000");
failures += !test(1000.123456    , "1,000.123456");
failures += !test(10000          , "10,000");
failures += !test(10000.123456   , "10,000.123456");
failures += !test(100000         , "100,000");
failures += !test(100000.123456  , "100,000.123456");
failures += !test(1000000        , "1,000,000");
failures += !test(1000000.123456 , "1,000,000.123456");
failures += !test(10000000       , "10,000,000");
failures += !test(10000000.123456, "10,000,000.123456");
if (failures) {
    console.log(`${failures} test(s) failed`);
} else {
    console.log("All tests passed");
}
.as-console-wrapper {
    max-height: 100% !important;
}

@ T.J.CROUDER は、JavaScriptにlookbehind( サポート情報 ) を使えば、正規表現そのもので解決できる。

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

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

function test(x, expect) {
    const result = numberWithCommas(x);
    const pass = result === expect;
    console.log(`${pass ? "✓" : "ERROR ====>"} ${x} => ${result}`);
    return pass;
}

let failures = 0;
failures += !test(0,               "0");
failures += !test(0.123456,        "0.123456");
failures += !test(100,             "100");
failures += !test(100.123456,      "100.123456");
failures += !test(1000,            "1,000");
failures += !test(1000.123456,     "1,000.123456");
failures += !test(10000,           "10,000");
failures += !test(10000.123456,    "10,000.123456");
failures += !test(100000,          "100,000");
failures += !test(100000.123456,   "100,000.123456");
failures += !test(1000000,         "1,000,000");
failures += !test(1000000.123456,  "1,000,000.123456");
failures += !test(10000000,        "10,000,000");
failures += !test(10000000.123456, "10,000,000.123456");
if (failures) {
    console.log(`${failures} test(s) failed`);
} else {
    console.log("All tests passed");
}
.as-console-wrapper {
    max-height: 100% !important;
}

(?<!\.\d*) は負のルックビハインドで、マッチの前に . の後に0桁以上の数字が続く。ネガティブルックビハインドの方が splitjoin ソリューション ( 比較 )、少なくともV8では。