js正則表達式之前瞻後顧與非捕獲分組
前瞻後顧與捕獲分組的結合使用
在現實的應用場景中,捕獲分組或非捕獲分組通常被限制在前瞻後顧條件內,舉例來說,對數字12345678格式化,結果為12,345,678。其正則實現如下:
let formatSum = '12345678'.replace(/\B(?=(?:\d{3})+(?!\d))/g, ',')
捕獲分組與非捕獲分組
為瞭理解前瞻與後顧,首先要先理解捕獲分組與非捕獲分組
在js中,
()表示捕獲分組,() 會把每個分組裡的匹配的值保存起來,使用$n(n是一個數字,表示第n個捕獲組的內容);
(?:)表示非捕獲分組,和捕獲分組唯一的區別在於,非捕獲分組匹配的值不會保存起來。
以formatSum 表達式為例,(?=(?:\d{3})+(?!\d)) ,(?:\d{3}) ,(?!\d) 都是分組,其中第二個分組是非捕獲分組。
前瞻、後顧與負前瞻、負後顧
在上述的formatSum表達式中,用到瞭 ‘?=‘與’?!’,這就是所謂的前瞻與負前瞻瞭。為瞭方便理解,我們以一個簡單的例子入手。
// 前瞻: A(?=B) //查找B前面的A // 後顧: (?<=B)A //查找B後面的A // 負前瞻: A(?!B) //查找後面不是B的A // 負後顧: (?<!B)A //查找前面不是B的A
回看formatSum表達式,將 (?:\d{3})+(?!\d) 視為一個整體表達式 A,即
formatSum = /\B(?=A)/g //此處A為表示式並非真正字母A,隻為方便理解
其意思是匹配表達式A前面的 \B ,而 \B 匹配的是非字母邊界,所以可以看出該表達式整體的作用是用來匹配並替換表達式 A 前邊的邊界的。
與 \B 對應的還有 \b ,其匹配字母邊界。對於初學者來說,邊界的概念比較難以理解,你可以把它看作是無形的 | ,任何長度大於等於2的字符串中都存在邊界。如 ‘ab’,它可以看作是’a|b’, 隻是此處 | 是無形的,當然它也就不計入字符串長度。
'ab'.replace(/\B/, ',') // a,b
接下來為瞭看表達式 A 部分: (?:\d{3})+(?!\d) 。
首先 ?: 表示非捕獲分組,\d{3} 表示3位數字,則 (?:\d{3})+ 表示3、6、9、12…位數字;
(?!\d) 為負前瞻,表示匹配後面不是數字的 (?:\d{3})+ 。綜上:
(?:\d{3})+(?!\d) 匹配'12345678'中後面不是數字的3*n(n=1遞增)位數字,即'678', '345678'
所以,得出結果:
formatSum = '12345678'.replace(/\B(?=(?:\d{3})+(?!\d))/g, ',') 匹配'12345678'中後面不是數字的3*n(n=1,n++)位數字前面的非字母邊界, 即'678', '345678'前面的非字母邊界,最終將這兩個邊界替換為逗號, 即 '3' 與 '6' 前加逗號
即
'12345678'.replace(/\B(?=(?:\d{3})+(?!\d))/g, ',') === '12,345,678' // true
總結
到此這篇關於js正則表達式之前瞻後顧與非捕獲分組的文章就介紹到這瞭,更多相關js正則前瞻後顧與非捕獲分組內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- pandas Dataframe實現批量修改值的方法
- 一文帶你徹底搞懂JavaScript正則表達式
- 深入淺出正則表達式中的邊界\b和\B
- 自學python求已知DNA模板的互補DNA序列
- 細說mysql replace into用法