解题思路
    (?=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)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。