[英]Custom filter with white space as thousands separator is not working
我試圖編寫一個自定義過濾器來過濾應用程序中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));
我不知道這是怎么回事。 任何幫助將不勝感激。
我終於使它工作了,問題出在我的Regex上,這是我用來格式化成千上萬個數字的最終正則表達式:
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));
問題在這里:
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));
您可以在上分割您的號碼.
然后將其拆分並轉換為數組,可以使用array#map
和array#filter
來獲得一個新數組,其元素按3個塊進行分組,然后只需reverse
並join
backl
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));
這是另一種基於我曾經編寫的“貨幣格式化程序”方法的方法:
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
“ thousandsSeparator”( \\d{3}\\THOUSANDS_SEPARATOR
)或字符串的末尾( \\d{3}$
)傳遞的字符。
第一個捕獲組( ^([^\\\\' + thousandsSeparator + '\\.]+)
)匹配所有不是的字符( 應該全部是數字...。您需要單獨檢查以確保這一點)小數點或作為“ thousandsSeparator”傳入的字符, 直到到達第二個捕獲組為止 。
注意:我在“ thousandsSeparator”之前添加了一個轉義斜杠,以防萬一有人在正則表達式中輸入了具有其他含義的內容,但即使如此,某些字符也可能在regex的執行中引起問題。 。 。 需要對其進行更多研究以使其更加安全。
只要能在值中找到這兩部分,它就會用“ 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
DEMO
$("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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.