解题思路
(?=p) 和 (?!p)
(?=p),其中 p 是一个子模式,即 p 前面的位置,或者说,该位置后面的字符要匹配 p。
比如 (?=l),表示 “l” 字符前面的位置,例如:
var result = “hello”.replace(/(?=l)/g, ‘#’);
console.log(result);
// => “he#l#lo”
而 (?!p) 就是 (?=p) 的反面意思,比如:
var result = “hello”.replace(/(?!l)/g, ‘#’);
console.log(result);
// => “#h#ell#o#”
比如把 “12345678”,变成 “12,345,678”。 可见是需要把相应的位置替换成 “,”。
一. 弄出最后一个逗号
使用 (?=\d{3}$) 就可以做到:
var result = “12345678”.replace(/(?=\d{3}$)/g, ‘,’)
console.log(result);
// => “12345,678”
其中,(?=\d{3}) 匹配 \d{3} 前面的位置。而 \d{3}$ 匹配的是目标字符串最后那 3 位数字。
二. 弄出所有的逗号
因为逗号出现的位置,要求后面 3 个数字一组,也就是 \d{3} 至少出现一次, 此时可以使用量词 +
var result = “12345678”.replace(/(?=(\d{3})+$)/g, ‘,’)
console.log(result);
// => “12,345,678”
三. 匹配其余案例
写完正则后,要多验证几个案例,此时我们会发现问题:
var result = “123456789”.replace(/(?=(\d{3})+$)/g, ‘,’)
console.log(result);
// => “,123,456,789”
因为上面的正则,仅仅表示把从结尾向前数,一但是 3 的倍数,就把其前面的位置替换成逗号。因此才会出现这个问题。
怎么解决呢?我们要求匹配的到这个位置不能是开头。
我们知道匹配开头可以使用 ^,但要求这个位置不是开头怎么办?
使用 (?!^),测试如下:
var regex = /(?!^)(?=(\d{3})+$)/g;
var result = “12345678”.replace(regex, ‘,’)
console.log(result);
// => “12,345,678”
result = “123456789”.replace(regex, ‘,’);
console.log(result);
// => “123,456,789”
代码
/*
@param {number} n
@return {string}
/
var thousandSeparator = function(n) {
return (n + ‘’).replace(/(?!^)(?=(\d{3})+$)/g,’.’)
};
作者:shetia
链接:https://leetcode-cn.com/problems/thousand-separator/solution/zheng-ze-wei-zhi-pi-pei-by-shetia/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
