最近在從新學習正則表達式,把在學習過程當中所遇到的案例,還有比較難理解概念用本身的理解分析並整理總結。git
若有哪些地方不對,歡迎指正,謝謝!(๑•ᴗ•๑)github
本系列使用的JavaScript
所支持的正則表達式語法,並推薦你使用 regexr.com/ 去作相應的練習。正則表達式
假定你已經熟悉元字符
,方括號
,修飾符
,量詞
及RegExp對象
。shell
若是沒有,請先看一遍文檔
www.w3school.com.cn/jsref/jsref…bash
本系列同步GitHub github.com/Janking/Blo…學習
$ ( ) * + . ? [ \ ^ {
ui
在文本中遇到 這幾種特殊字符想轉爲文本,須要經過反斜槓\
轉義:spa
/\$ \( \) \* \+ \. \? \[ \\ \^ \{/g
code
也許你會問到 -
減號符,}
右花括號,]
右中括號爲什麼不在內?首先減號符是在[]
中的,在前面沒與到轉義的[
左方括號時,減號符及右方括號-]
是當普通文本處理,無需轉義,而花括號也如此regexp
/\{\w+}\[hello-world]/
{abc}[hello-world] hey! hey! hey!
若是須要匹配一個 yyyy-mm-dd
格式的日期,其中月份和日期都是年份的個十位
/\b\d\d(\d\d)-\1-\1\b/
反斜槓\1-9
能夠獲得前面分組(\d\d)
捕獲到的結果,若是是10-99呢?那就\10
至\99
/\b\d\d(\d\d)-\1-\1\b/
2008-08-08
單詞邊界這個概念我開始比較抽象,也花了點時間去實踐究竟是啥,因此在這裏做爲一個案例來講說。
在單詞邊界匹配的位置,單詞字符後面或前面不與另外一個單詞字符直接相鄰。 不太明白,仍是看實例吧!
"That dang-tootin' #!@#$ varmint's cost me $199.95!".replace(/\b/g,function(){
console.log(arguments)
});複製代碼
//output
["", 0, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 4, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 5, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 9, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 10, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 16, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 24, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 31, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 32, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 33, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 34, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 38, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 39, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 41, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 43, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 46, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 47, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]
["", 49, "That dang-tootin' #!@#$ varmint's cost me $199.95!"]複製代碼
經過控制檯輸出,咱們能夠發現\b
匹配的位置以下:
細心的你必定會發現數字的開始,小數點的左右都會有單詞邊界,這意味着單詞邊界不單單是英文字母,還包括數字。
\b
屬於匹配位置的元字符,通常做佔位做用,而不被捕獲,同屬於匹配位置的還有匹配行起始位^
和行結束位$
24小時制能夠分爲三段:
先匹配第一階段: /[0][0-9]/
再接着匹配第二階段:/[01][0-9]/
第三階段以此類推?/[012][0-9]/
明顯不合適,由於不可能出現大於23以上的數字,那麼只能開分支了 /[01][0-9]|2[0-3]/
也許你會說,00-09若是要匹配「沒有補零」的狀況呢?(即:0,1,2,3,4,5...)
咱們能夠藉助一下量詞?
匹配 /[01]?[0-9]|2[0-3]/
/[01]?[0-9]|2[0-3]/
咱們在一些場景裏須要將7654321輸出成7,654,321這樣的格式,這就是千分位,用正則表達式去處理的話,關鍵是獲取位置,那麼首先想到的就是要利用非單詞邊界\B,下面這條正則是能成功取得千分位的位置的:
/\B(?=(\d{3})+(?!\d))/g
先將這個正則分解成三部分:
1 )、 /\B(?=\d)/
這是\B
是爲了防止出現,123
起始位置被匹配的問題,(?=\d)
是非單詞邊界後緊跟數字
2 )、 嘗試一下8位數的數字: '12345678' 在 /\B(?=(\d{3})+)/
匹配獲得什麼結果呢?
// input
'12345678'.replace(/\B(?=(\d{3})+)/g,function(){console.log(arguments);return '|'})複製代碼
// output
["", "567", 1, "12345678"]
["", "678", 2, "12345678"]
["", "456", 3, "12345678"]
["", "567", 4, "12345678"]
["", "678", 5, "12345678"]
"1|2|3|4|5|678"複製代碼
首先符合非單詞邊界\B
的有1,2,3,4,5,6,7的右邊位置,然後面也一樣緊跟數字2,3,4,5,6,7
其次符合\d{3}
的有234,345,456,567,678,但後面跟個加號+
結果就不同了
那爲何會獲得567,678,456,567,678,這樣奇怪的匹配?原理以下:
1. 匹配`\B`第1個非單詞邊界 `1`的右邊位置,則後面(\d{3})+的結果爲:23四、567,8後面沒法補齊3位,匹配獲得567
2. 匹配`\B`第2個非單詞邊界 `2`的右邊位置,則後面(\d{3})+的結果爲:34五、678,匹配獲得678
3. 匹配`\B`第3個非單詞邊界 `3`的右邊位置,則後面(\d{3})+的結果爲:45六、78後面沒法補齊3位,匹配獲得456
4. 匹配`\B`第4個非單詞邊界 `4`的右邊位置,則後面(\d{3})+的結果爲:56七、8後面沒法補齊3位,匹配獲得567
5. 匹配`\B`第5個非單詞邊界 `5`的右邊位置,則後面(\d{3})+的結果爲:678
6. 匹配`\B`第6個非單詞邊界 `6`的右邊位置,但78沒法補齊3位,
7. 同6
8. 最終小括號分組匹配獲得的分別是:567,678,456,567,678複製代碼
3 )、最後 (?!\d) 是前面匹配成功後跟的非數字,那連起來就是:
1. 匹配`\B`第1個非單詞邊界 `1`的右邊位置,則後面(\d{3})+的結果爲:23四、567,後面跟着8,不匹配
2. 匹配`\B`第2個非單詞邊界 `2`的右邊位置,則後面(\d{3})+的結果爲:34五、678,後面跟着非數字,位置匹配成功
3. 匹配`\B`第3個非單詞邊界 `3`的右邊位置,則後面(\d{3})+的結果爲:456,後面跟着七、8不匹配
4. 匹配`\B`第4個非單詞邊界 `4`的右邊位置,則後面(\d{3})+的結果爲:567,後面跟着8,不匹配
5. 匹配`\B`第5個非單詞邊界 `5`的右邊位置,則後面(\d{3})+的結果爲:678,後面跟着非數字,位置匹配成功
6. 最終獲得獲得可插入逗號的位置爲2,5複製代碼