小弟自己上網找了用正規表達式和 replace() 處理千位分隔符的問題,但找到的寫法有點看不懂~
我知道 \B
可以比對非英文字的邊界,自己嘗試著把 \B
拿掉,則原本的 10000 和 -10000 會呈現 ,100,000 和 -,100,000 的結果。重新加入 \B
後最前面就沒逗號 ,
了,這個背後原理是什麼啊??請大大解釋一下了,感謝~~
function change(num) {
// \B: 比對非英文的邊界
// ?=(\d{3}): 取出3位數字出來
// +(?!\d): 該3位數字後面接著非數字的字元
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
console.log(change(0));
console.log(change(1234567.90));
console.log(change(-1234567.90));
console.log(change(100000));
console.log(change(-100000));
console.log(change(1234567.9876531));
\B 就是 non-word boundary
由於你的正則內是字位位數來產生空值插入[,]。
但如果開頭剛剛好也是在計算位置的情況。也是會出現,。
這其實並不是我們想要的。
所以\B就會達到分隔處理的效果。
用比較白話點的就是告訴正則。開頭位元不需要處理,就算符合的情況下。
它只是盡了區分的責任。
推間一個網站給您學習,我是這網站入門regex的
正则表达式30分钟入门教程
表3.常用的反义代码
代码/语法 | 说明 |
---|---|
\W | 匹配任意不是字母,数字,下划线,汉字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非数字的字符 |
\B | 匹配不是单词开头或结束的位置 |
[^x] | 匹配除了x以外的任意字符 |
[^aeiou] | 匹配除了aeiou这几个字母以外的任意字符 |
想要練習的話可以在這裡線上測試您的regex
https://regexr.com/
我說說我的理解,但不一定正確。
首先將正規式拆成四個部分
\B
(\d{3})+
(?!\d)
(?=...)
\b 是比對一個詞的邊界,而 \B 是反義,代表不是一個詞的邊界
這裡的詞是指連續的 英文
、數字
、_
-10000 會被拆成兩個詞 -
和 10000
而 \B 代表不匹配詞邊界,所以開頭的 - 和 1 才沒有被匹配
\d 代表匹配數字
{3} 代表 3 個數字
()+ 代表裡面的內容可以符合 1~N 次
這裡比較好理解,就是3個數字分一組
(?!) 和最外面的 (?=) 中文翻譯是斷言
不過從字面上很難看出它的用途,哈哈哈
(?!) 是不匹配的意思
xxx(?!\d): xxx 後面不能是數字的意思
這個是後面必須符合但不能匹配的意思
xxx(?=bbb): xxx 後面必須符合 bbb 的規則,但不把 bbb 匹配進去
有點難懂,舉例 xxxbbb
bbb 雖然被匹配,但結果只會取得 xxx
最後合起來的比對方式和我開始想的不太一樣,還蠻有趣的
雖然比對是由前往後,但由後往前看會比較清楚
因為要符合 (?!\d) 這個條件
所以可以先將 1234567.9876531 拆成 1234567. 和 9876531
接著因為從 1 開始沒辦法分成 3個3個一組,所以比對失敗
往下一位 2 去比,這時候比對成功
但因為 (?=) 不匹配的關係,只會取 \B 出來 (圖中第一條紫色線)
雖然 234567 已經被比對了,但因為 (?=) 的關係
所以正規式還是可以回頭繼續比對 567 (圖中第二條紫色線)
這裡我覺得是這個正規式精妙的地方
因為正常的比對,比過的地方就不能回頭
這邊利用了 (?=) 不匹配的特性
使正規式還可以回頭,繼續找後面的數字
這是小弟的理解,如果有錯誤再請各位大大指正。
好詳細的回覆啊~這樣我就比較了解整段程式碼的意思了,非常感謝~
可惜最佳解答只能一個...不然想把你寫的東西設定為最佳解答啊哈哈
\d{3}
匹配3個數字,+表示前面的内容重複1到多次,所以 (\d{3})+
表示三個數字的1到多次,也就是3,6,9...等3的倍數個數字的字串(?!\d)
匹配一个位置,此位置後面不是數字(?=(\d{3})+(?!\d))
匹配一个位置,這個位置後面首先是3的倍數個數字的字串,接下来的位置不是數字/\B(?=(\d{3})+(?!\d))/g
就是全部匹配一个位置,這個位置前面要有字元存在,然後後面是3的倍數個數字,再後面是非數字。以上,是我個人整理出來的最終理解,都可以討論看看喔~
/\B(?=(\d{3})+(?!\d))/g 就是全部匹配一个位置,這個位置前面要有字元存在,然後後面是3的倍數個數字,再後面是非數字。
是這個意思沒錯!
你這樣一步一步的拆解說明很清楚,哈哈哈。