我正在尝试用逗号作为千位分隔符在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; }
有没有更简单或更优雅的方法来做到这一点?如果它也适用于浮点数会很好,但这不是必需的。在句点和逗号之间决定不需要特定于语言环境。
简化了它,因为我只是为我的特定目的寻找简单的东西。这是我所拥有的:
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 个前瞻断言:
例如,如果你通过它123456789.01,肯定断言将匹配 7 左边的每个点(因为789是 3 位678的倍数,是 3 位的倍数567,等等)。否定断言检查 3 位的倍数后面没有任何数字。789后面有一个句点,所以它正好是 3 位数字的倍数,所以用逗号。678是 3 位数字的倍数,但它9后面有一个,所以这 3 位数字是一组 4 的一部分,逗号不会去那里。同样对于567。456789是 6 位数字,是 3 的倍数,所以逗号放在前面。345678是 3 的倍数,但9后面有一个,所以没有逗号。等等。这\B防止正则表达式在字符串的开头放置逗号。
123456789.01
789
678
567
9
456789
345678
\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; }
@tjcrowder指出,现在 JavaScript 有lookbehind(支持信息),可以在正则表达式本身解决:
function numberWithCommas(x) { return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ","); }
Hide code snippet
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,表示匹配项前面不能有a,.后跟零个或多个数字。至少在 V8 中,否定的lookbehind 比splitandjoin解决方案。
(?<!\.\d*)
.
split
join
我很惊讶没有人提到Number.prototype.toLocaleString。它是在 JavaScript 1.5(于 1999 年推出)中实现的,因此基本上所有主流浏览器都支持它。
var n = 34523453.345; console.log(n.toLocaleString()); // "34,523,453.345"
从 v0.12 开始,它也可以通过包含Intl在 Node.js 中工作
如果你想要不同的东西,Numeral.js可能会很有趣。