【发布时间】:2009-12-16 10:10:21
【问题描述】:
是否可以使用单程和仅正则表达式进行数字分组(例如,将数字1000转换为字符串"1 000")? (我知道在某些系统中,正则表达式和语言设施之间的界限有些模糊 - 在回复之前听听你的良心。)
我问的原因:另一位开发人员最近问我如何在 JavaScript 中进行数字分组,并向我展示了一个使用正则表达式的 JavaScript 函数稍微不正确。我给了他a better alternative,但他的正则表达式对我唠叨,因为这种重写绝对是常规语法应该能够做的事情,但我真的不知道如何为其编写正则表达式。
这是我第一次天真的尝试,我知道这是不正确的:
function group(n) { return n.toString().replace(/(\d{3})/g, "$1 "); }
这种方法有两个缺陷; group(1000) 产生 "100 0",group(100) 产生 "100 "(尾随空格)。你可以这样修复它:
String.prototype.reverse = function () {
var a = [];
for (var i = this.length; i >= 0; --i) a.push(this[i]);
return a.join("");
};
function group(n) {
return n.toString().reverse().replace(/(\d{3})/g, "$1 ").
trimRight().reverse();
}
但这需要的不是一次,不是两次,甚至不是三次,而是四次传球(两次反转,一次替换和trimRight)!然后我冒险进入后视区,并想出了:
function group(n) { return n.toString().replace(/(\d{3}(?!\d))/g, " $1");
...这根本不起作用(编辑 - 可能是因为我混淆了后视和负前瞻...) - 它只匹配最后三个数字(@987654333 @ 变为 "1000000 000")。前瞻效果更好:
function group(n) { return n.toString().replace(/(\d{3})(?=\d)/g, "$1 "); }
这或多或少让我回到了我开始的地方 - 我摆脱了尾随空格,但group(1000) 仍然产生"100 0"。
那么 - 这可以通过单个正则表达式替换传递来完成吗?我与语言无关,因为这应该只需要使用正则表达式工具。
注意:这不是关于如何进行本地化的问题,我也没有进行过早的优化。我只是好奇这是否可能,如果不可能,为什么不呢。
【问题讨论】:
-
仅供参考,
(?!\d)不是后视,而是负前瞻。 -
@Alan Moore - 天哪!这就解释了为什么它不起作用。 :)
-
我知道这不是关于如何进行本地化,但如果有人为此而来,请使用Number.toLocaleString