カンマを千単位の区切りとして数値をフォーマットするにはどうすればいいですか? 質問する

カンマを千単位の区切りとして数値をフォーマットするにはどうすればいいですか? 質問する

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

console.log(numberWithCommas(1000))

もっとシンプルまたはエレガントな方法はありますか? フロートでも動作すれば良いのですが、必須ではありません。ピリオドとカンマの区別をロケール固有にする必要はありません。

ベストアンサー1

私はケリーの回答のアイデアを使用しましたが、特定の目的のために単純なものを探していただけだったので、それを簡略化しました。これが私の考えです:

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、肯定アサーションでは 7 の左側のすべての位置が一致します (789は 3 桁の倍数で、678は 3 桁の倍数、567などであるため)。否定アサーションでは、3 桁の倍数の後ろに数字がないことをチェックします。789の後ろにはピリオドがあるため、ちょうど 3 桁の倍数なので、ここにカンマが入ります。678は 3 桁の倍数ですが、その後に があるため9、これら 3 桁は 4 桁のグループの一部であり、ここにはカンマが入りません。 も同様です567456789は 6 桁で 3 の倍数なので、その前にカンマが入ります。は 3 の倍数ですが、その後に が345678あるため、ここにはカンマが入りません。以下同様に続きます。 は、正規表現で文字列の先頭にカンマが置かれるのを防ぎます。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;
}

@翻訳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 個以上の数字が続くことはできないと示しています。否定的な後読みはsplitandjoinソリューションよりも高速です (比較(少なくとも V8 では)

おすすめ記事