鍍金池/ 問答/網(wǎng)絡(luò)安全  HTML/ 這個千分符的正則誰來幫我解釋下

這個千分符的正則誰來幫我解釋下

正則來源:
https://github.com/anran758/F...

/**
 * 千位分隔符
 *
 * @param {Number} num - 金額
 * @returns 返回格式化后的數(shù)字
 */
function numberWithCommas(num) {
  // 正則解釋: 匹配到 \B(非單詞邊界)后, 后面要匹配到 (\d{3})+(?!\d)
  // (\d{3})+ 至少匹配到一次或多次三個數(shù)字
  // (?!\d) 同時后面不是數(shù)字的話, 就匹配.
  // 注意, 后面的(?=)那一段代碼只是判斷的規(guī)則, 匹配到后只替換掉\B
  // 這是一個很巧妙的方法 ..
  return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

// '12,345'
'12345'.replace(/\B(?=(\d{3})+(?!\d))/g, ',');

// '123,456e'
'123456e'.replace(/\B(?=(\d{3})+(?!\d))/g, ',');

這里用到了正則的幾個形式如下(摘自百科):

\B
匹配非單詞邊界?!癳r\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。

\d
匹配一個數(shù)字字符。等價于[0-9]。grep 要加上-P,perl正則支持
(?=pattern)
非獲取匹配,正向肯定預(yù)查,在任何匹配pattern的字符串開始處匹配查找字符串,該匹配不需要獲取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。預(yù)查不消耗字符,也就是說,在一個匹配發(fā)生后,在最后一次匹配之后立即開始下一次匹配的搜索,而不是從包含預(yù)查的字符之后開始。

(?!pattern)
非獲取匹配,正向否定預(yù)查,在任何不匹配pattern的字符串開始處匹配查找字符串,該匹配不需要獲取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。

{n}
n是一個非負(fù)整數(shù)。匹配確定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的兩個o。

+
匹配前面的子表達(dá)式一次或多次(大于等于1次)。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等價于{1,}。

(pattern)
匹配pattern并獲取這一匹配。所獲取的匹配可以從產(chǎn)生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中則使用$0…$9屬性。要匹配圓括號字符,請使用“\(”或“\)”。

從我的理解 這里是要匹配\B,但是要求后面必須是3個數(shù)字且末尾不能是數(shù)字,那這樣的話,只能匹配到 123456e這個字符串中的4前面那個位置才對
12345這個就不符合匹配,因為它不符合我理解的末尾不能是數(shù)字,不能匹配到才對,可是結(jié)果卻匹配到了

正則對我來說還算一個比較新的塊,所以求大佬指教

回答
編輯回答
厭惡我

而且這個正則還有個bug
console.log(numberWithCommas(12345678912.1234))
12,345,678,912.1,234
小數(shù)后面不能正確處理,不知道哪位大神可以幫忙修正下

20180606更新:
自己這幾天沒事就關(guān)注下正則,整了個答案:

clipboard.png

/(B(?=(d{3})+(?!d)D))|(B(?<=D(d{3})+))/g

2018年1月23日 23:07