我正在尝试编写自定义过滤器,以便在我的应用程序中以xxx xxx,xxx
格式过滤数字。
这是我到目前为止所写的功能:
var formatNumber = function(input, fractionSeparator, thousandsSeparator, fractionSize) {
fractionSeparator = fractionSeparator || ',';
thousandsSeparator = thousandsSeparator || ' ';
fractionSize = fractionSize || 3;
var output = '', parts = [];
input = input.toString();
parts = input.split(".");
output = parts[0].replace(/(\d{3})/g, ""+ thousandsSeparator +"$1").trim();
if(parts.length>1){
output += fractionSeparator;
output += parts[1].substring(0, fractionSize);
}
return output;
};
实际上,此功能对某些数字非常有效,但在其他情况下失败,例如:
使用以下数字:
451.585478
,它会打印451,585
。154455451.58
,它会打印154 455 451,58
。这些例子失败:
对于54455451.58
,它会打印54455 451,58
。
对于55451.58
,它会打印55451,58
。
演示:
var formatNumber = function(input, fractionSeparator, thousandsSeparator, fractionSize) {
fractionSeparator = fractionSeparator || ',';
thousandsSeparator = thousandsSeparator || ' ';
fractionSize = fractionSize || 3;
var output = '',
parts = [];
input = input.toString();
parts = input.split(".");
output = parts[0].replace(/(\d{3})/g, "" + thousandsSeparator + "$1").trim();
if (parts.length > 1) {
output += fractionSeparator;
output += parts[1].substring(0, fractionSize);
}
return output;
};
console.log(formatNumber(154455451.58));
console.log(formatNumber(55451.58));
console.log(formatNumber(54455451.58));

我不知道它有什么问题。任何帮助将不胜感激。
我终于得到了它的工作,问题出在我的正则表达式,这是我用来格式化数千的最终正则表达式:
output = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandsSeparator).trim();
这是最终的代码:
var formatNumber = function(input, fractionSeparator, thousandsSeparator, fractionSize) {
fractionSeparator = fractionSeparator || ',';
thousandsSeparator = thousandsSeparator || ' ';
fractionSize = fractionSize || 3;
var output = '',
parts = [];
input = input.toString();
parts = input.split(".");
output = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandsSeparator).trim();
if (parts.length > 1) {
output += fractionSeparator;
output += parts[1].substring(0, fractionSize);
}
return output;
};
console.log(formatNumber(154455451.58));
console.log(formatNumber(55451.58));
console.log(formatNumber(54455451.58));

答案 0 :(得分:1)
问题在于:
output = parts[0].replace(/(\d{3})/g, ""+ thousandsSeparator +"$1").trim();
您在每3个数字之前插入空格(我会在括号之间标记匹配):
"(123)(456)78" --> "( 123)( 456)78"
然后你正在修剪它 - > "123 45678"
你的想法很好,但你必须从右到左开始这样做,所以我会反转parts[0]
和替换:
parts[0] = parts[0].split('').reverse().join('');
"12345678" --> "87654321"
parts[0] = parts[0].replace(/(\d{3})/g, "$1" + thousandsSeparator).trim();
"(876)(543)21" --> "(876 )(543 )21"
output = parts[0].split('').reverse().join('');
"876 543 21" --> "12 345 678"
您想要的输出是什么。这是更新的代码段:
var formatNumber = function(input, fractionSeparator, thousandsSeparator, fractionSize) {
fractionSeparator = fractionSeparator || ',';
thousandsSeparator = thousandsSeparator || ' ';
fractionSize = fractionSize || 3;
var output = '',
parts = [];
input = input.toString();
parts = input.split(".");
parts[0] = parts[0].split('').reverse().join('');
parts[0] = parts[0].replace(/(\d{3})/g, "$1" + thousandsSeparator).trim();
output = parts[0].split('').reverse().join('');
if (parts.length > 1) {
output += fractionSeparator;
output += parts[1].substring(0, fractionSize);
}
return output;
};
console.log(formatNumber(154455451.58));
console.log(formatNumber(55451.58));
console.log(formatNumber(54455451.58));
答案 1 :(得分:1)
您可以在.
上拆分号码,然后拆分它并将其转换为数组,并可以使用array#map
和array#filter
获取一个新数组,其元素分组为块3然后你必须reverse
和join
它后退
const formatNumber = (num, fractionSeparator, thousandsSeparator, fractionSize) => {
fractionSeparator = fractionSeparator || ',';
thousandsSeparator = thousandsSeparator || ' ';
fractionSize = fractionSize || 3;
let [first, second] = num.toString().split('.');
let reversed = first.split('').reverse();
reversed = reversed.map((e,i) => i%fractionSize===0 ? reversed.slice(i,i+fractionSize).join('') :null)
.filter(x => x)
.reverse()
.join(thousandsSeparator);
return reversed + fractionSeparator + second;
}
console.log(formatNumber(154455451.58));
console.log(formatNumber(55451.58));
console.log(formatNumber(54455451.58));
答案 2 :(得分:1)
这是另一种基于我曾经写过的“货币格式化程序”方法的方法:
var sRegexFormatPattern = '^([^\\' + thousandsSeparator +
'\.]+)(\\d{3}[\\' + thousandsSeparator +
'\.]|\\d{3}$)';
var regexFormatPattern = new RegExp(sRegexFormatPattern);
while (regexFormatPattern.test(input)) {
input = input.replace(regexFormatPattern, '$1' + thousandsSeparator + '$2');
}
让我们从后到前打破正则表达式。 。
第二个捕获组((\\d{3}[\\' + thousandsSeparator + '\.]|\\d{3}$)
)恰好匹配3位数字和小数点(\d{3}\.
),传入的字符为“千位分离器”(\d{3}\THOUSANDS_SEPARATOR
),或字符串的结尾(\d{3}$
)。
第一个捕获组(^([^\\' + thousandsSeparator + '\.]+)
)匹配所有字符(应都是数字... ...您需要单独检查以确保这一点)不是小数点,也不是作为“千位分离器”传入的字符,直到它击中第二个捕获组。
注意:我在“千位分隔符”之前添加了一个转义斜杠,以防万一有人在正则表达式中输入了另一个含义的东西,但是,即便如此,某些字符也可能导致问题。执行正则表达式。 。 。需要更多地调查它以使其万无一失。
只要它能在值中找到这两个部分,它就会用“千位分隔符”将它们分解并再次检查。以“12345678.90”为例,迭代如下:
12345
678.
---将数字更改为---> 12345 678.90 12
345 678.
---将数字更改为---> 12 345 678.90 该部分之前和之后的所有内容或多或少都是您已有的。 。 。我添加了一个小调整,你是如何格式化字符串的“分数”部分,但其余部分几乎相同(请参阅下面的完整JS代码)。
使用您的测试值,我得到了:
- 451.585478 ---> 451,585
- 154455451.58 ---> 154 455 451,58
- 54455451.58 ---> 54 455 451,58
- 55451.58 ---> 55 451,58
<强>样本强>
$("document").ready(function() {
$(".formattingInput").on("change", function() {
$("#formattedNumber").text(formatNumber(
$("#unformattedNumberInput").val(),
$("#fractionSeparator").val(),
$("#thousandsSeparator").val(),
$("#fractionSize").val()
));
});
});
var formatNumber = function(input, fractionSeparator, thousandsSeparator, fractionSize) {
fractionSeparator = fractionSeparator || ',';
thousandsSeparator = thousandsSeparator || ' ';
fractionSize = fractionSize || 3;
var sRegexFormatPattern = '^([^\\' + thousandsSeparator +
'\.]+)(\\d{3}[\\' + thousandsSeparator +
'\.]|\\d{3}$)';
var regexFormatPattern = new RegExp(sRegexFormatPattern);
while (regexFormatPattern.test(input)) {
input = input.replace(regexFormatPattern, '$1' + thousandsSeparator + '$2');
}
var parts = input.split('.');
if (parts.length > 1) {
input = parts[0] +
fractionSeparator +
parts[1].substring(0, fractionSize);
}
return (input.length > 0) ? input : 'Please input a value in the "Number" field.';
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<label for="unformattedNumberInput">Number: <input type="text" id="unformattedNumberInput" class="formattingInput" /></label><br />
<label for="thousandsSeparator">Thousands Separator: <input type="text" id="thousandsSeparator" class="formattingInput" /></label><br />
<label for="fractionSeparator">Fraction Separator: <input type="text" id="fractionSeparator" class="formattingInput" /></label><br />
<label for="fractionSize">Fraction Size: <input type="text" id="fractionSize" class="formattingInput" /></label><br /><br />
</div>
<div>
<strong>Result:</strong>
<span id="formattedNumber">Please input a value in the "Number" field.</span>
</div>