JS 正则中环视(断言)应用 -- 数字千分符

介绍一下顺序环视 (?=...) 和逆序环视 (?<=...) 
方便不想看长文的人,如果在支持 ES2018 的环境中整数可以这样使用:

String(12345678).replace(/(?<=\d)(?=(\d{3})+\b)/g, ‘,‘) // "12,345,678"

其中最关键的是肯定顺序环视(?=...),也叫零宽度正预测先行断言
添加千分符麻烦的地方在于只有在从右到左 3 的倍数的位数和前面的数字中间需要添加逗号
而正则是从左到右匹配的,这时候就需要用到顺序肯定环视。
环视不占用字符,能匹配到符合要求的位置
比如,`/Java(?=Script)/` 只会匹配后面有 Script 的 Java 字符

‘Java or JavaScript‘.replace(/Java(?=Script)/, ‘Type‘); // "Java or TypeScript"

我们知道匹配连续的 3 个数字的方法是 /\d{3}/ 3 的倍数的位数的数字就是 /(\d{3})+/
再结合顺序肯定环视,我们就能匹配到后面有 3 的倍数的位数前面的位置 /(?=(\d{3})+)/

这样我们就成功一半了,下面的问题是 `123456` 这样的 6 位数,前面不需要加分隔符。
所以我们还需要匹配前面有数字的位置,这就需要肯定逆序环视 /(?<=\d)/
逆序环视和顺序环视相反,是指定模式后面的位置比如:

‘Adding subscripts using Javascript‘.replace(/(?<=Java)script/, ‘Script‘); // "Adding subscripts using JavaScript"

上面两个加起来就可以匹配到前面有数字,且后面有 3 的倍数的位置,但如果你这样子写:

String(12345678).replace(/(?<=\d)(?=(\d{3})+)/g, ‘,‘); // "1,2,3,4,5,678"

会发现和预期不同,右边三位数字前面的每个数字后都加了逗号。
我们可以使用单词分隔符 `\b` 来解决这个问题

String(12345678).replace(/(?<=\d)(?=(\d{3})+\b)/g, ‘,‘) // "12,345,678"

如果你是在支持 ES2018 环境下运行那到这里就可以了,但目前很多浏览器还不支持逆序环视。好在我们可以稍微变通,不使用逆序环视来解决

String(12345678).replace(/(\d{1,3})(?=(\d{3})+\b)/g, ‘$1,‘) // "12,345,678"

为了方便可以添加一个函数

function formatNumber(number) {
    if (typeof number !== ‘number‘) {
        throw new Error(‘formatNumber parameter must be number‘);
    }
    if (Number.isNaN(number)) {
        return ‘0‘;
    }
    let result;
    const [integerNum, decimalNum] = String(number).split(‘.‘);
    return integerNum.replace(/(\d)(?=(\d{3})+\b)/g, ‘$1,‘) + (decimalNum ? `.${decimalNum}` : ‘‘);
}

如果想用国内的习惯,按万位划分,把 3 改 4 即可

原文地址:https://www.cnblogs.com/liyan-web/p/12079923.html

时间: 2024-10-08 07:32:20

JS 正则中环视(断言)应用 -- 数字千分符的相关文章

金钱数字千分符

function initNumber(number) { number= (typeof number=='number') ? number.toString() : number; var len = number.length; var newnumber = ""; for (var i = 0; i < len; i++) { if ((i + 1) % 3 == 0) { newnumber += number.substr(0, 3) + ","

js解决千分符问题

js脚本function: //js数字千分符处理 function commafy(num) { num = num + ""; var re = /(-?\d+)(\d{3})/ while (re.test(num)) { num = num.replace(re, "$1,$2") } return num; }

js解决千分符问题[收藏下]

//js数字千分符处理 function commafy(num) { num = num + ""; var re = /(-?\d+)(\d{3})/ while (re.test(num)) { num = num.replace(re, "$1,$2") } return num; } 执行下,效果不错,收藏记录

JS数字千分

JS数字千分: 1.例子:1000--->1,000 2.实现如下: salesToFormat: function (num) { var num = (num || 0).toString(), result = ''; while (num.length > 3) {//拿掉num的最后三位给result result = ',' + num.slice(-3) + result; num = num.slice(0, num.length - 3); } if (num) { resu

js-格式化数字保留两位小数-带千分符

很多时候发现有时候js会提示自带函数不能使用,所以自己找了很多资料实现了个 html <input type="text" class="input_text input_number" name="mgsy_dbnfjlr" value="" onblur="this.value=fouces_qfh(this.value)" /> js函数 function fouces_qfh(obj){

java 数字转为千分符格式字符串,将千分符格式字符串反转为数字

int a = 2000;String str = NumberFormat.getIntegerInstance(Locale.getDefault()).format(a); //转为千分符字符串System.out.println(str); try { int b = NumberFormat.getIntegerInstance(Locale.getDefault()).parse(str).intValue(); //转为数字 System.out.println("" +

js-处理千分符

/** * 去除千分符 */ function commafyback(num) { var x = num.split(','); return parseFloat(x.join("")); } /** * 增加千分符 */ function commafy(num) { num = num.toFixed(2) + ""; var re = '/(-?/d+)(/d{3})/'; while (re.test(num)) { num = num.replace

JS 正则中的命名捕获分组

假设你在一段陌生的代码中看到这样一个函数: function toLocalDate(date) { return date.replace(/(\d{2})-(\d{2})-(\d{4})/, "$2-$1-$3") } 单看这个函数你能知道它是想把“日-月-年”替换成“月-日-年”,还是反过来?匿名捕获分组没法做到这一点,那就该命名捕获分组上场了: function toLocalDate(date){ return date.replace(/(?<month>\d{

JS实现数字千位符格式化方法

/** * * @param num * @param precision * @param separator * @returns {*} *======================================================= * formatNumber(10000)="10,000" * formatNumber(10000, 2)="10,000.00" * formatNumber(10000.123456, 2)="