問題描述
我正在嘗試在 JavaScript 中打印一個整數,并用逗號作為千位分隔符.例如,我想將數字 1234567 顯示為1,234,567".我該怎么做呢?
I am trying to print an integer in JavaScript with commas as thousands separators. For example, I want to show the number 1234567 as "1,234,567". How would I go about doing this?
這是我的做法:
function numberWithCommas(x) {
x = x.toString();
var pattern = /(-?d+)(d{3})/;
while (pattern.test(x))
x = x.replace(pattern, "$1,$2");
return x;
}
有沒有更簡單或更優雅的方法來做到這一點?如果它也適用于浮點數會很好,但這不是必需的.在句點和逗號之間決定不需要特定于語言環境.
Is there a simpler or more elegant way to do it? It would be nice if it works with floats also, but that is not necessary. It does not need to be locale-specific to decide between periods and commas.
推薦答案
我使用了 Kerry 的回答中的想法,但簡化了它,因為我只是為我的特定目的尋找簡單的東西.這是我所擁有的:
I used the idea from Kerry's answer, but simplified it since I was just looking for something simple for my specific purpose. Here is what I have:
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 個前瞻斷言:
The regex uses 2 lookahead assertions:
- 一個正數,用于查找字符串中后面連續有 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
防止正則表達式在字符串開頭放置逗號.
For example, if you pass it 123456789.01
, the positive assertion will match every spot to the left of the 7 (since 789
is a multiple of 3 digits, 678
is a multiple of 3 digits, 567
, etc.). The negative assertion checks that the multiple of 3 digits does not have any digits after it. 789
has a period after it so it is exactly a multiple of 3 digits, so a comma goes there. 678
is a multiple of 3 digits but it has a 9
after it, so those 3 digits are part of a group of 4, and a comma does not go there. Similarly for 567
. 456789
is 6 digits, which is a multiple of 3, so a comma goes before that. 345678
is a multiple of 3, but it has a 9
after it, so no comma goes there. And so on. The B
keeps the regex from putting a comma at the beginning of the string.
@neu-rah 提到如果后面有超過 3 個數字,這個函數會在不需要的地方添加逗號小數點.如果這是一個問題,你可以使用這個功能:
@neu-rah mentioned that this function adds commas in undesirable places if there are more than 3 digits after the decimal point. If this is a problem, you can use this function:
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;
}
@tjcrowder 指出,現在 JavaScript 有lookbehind (支持信息),可以在正則表達式本身解決:
@t.j.crowder pointed out that now that JavaScript has lookbehind (support info), it can be solved in the regular expression itself:
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*)
是一個否定的lookbehind,表示匹配項前面不能有 .
后跟零個或多個數字.負面的lookbehind比split
和join
解決方案更快(比較),至少在 V8 中.
(?<!.d*)
is a negative lookbehind that says the match can't be preceded by a .
followed by zero or more digits. The negative lookbehind is faster than the split
and join
solution (comparison), at least in V8.
這篇關于如何在 JavaScript 中用逗號打印一個數字作為千位分隔符的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!