正則表達式案例分析 (一)

前言

最近在從新學習正則表達式,把在學習過程當中所遇到的案例,還有比較難理解概念用本身的理解分析並整理總結。git

若有哪些地方不對,歡迎指正,謝謝!(๑•ᴗ•๑)github

本系列使用的JavaScript所支持的正則表達式語法,並推薦你使用 regexr.com/ 去作相應的練習。正則表達式

假定你已經熟悉元字符方括號修飾符,量詞RegExp對象shell

若是沒有,請先看一遍文檔
www.w3school.com.cn/jsref/jsref…bash

本系列同步GitHub github.com/Janking/Blo…學習

案例分析

(1) 須要轉義的特殊字符

$ ( ) * + . ? [ \ ^ { ui

在文本中遇到 這幾種特殊字符想轉爲文本,須要經過反斜槓\轉義:spa

/\$ \( \) \* \+ \. \? \[ \\ \^ \{/g code

也許你會問到 -減號符,}右花括號,]右中括號爲什麼不在內?首先減號符是在[]中的,在前面沒與到轉義的[左方括號時,減號符及右方括號-]是當普通文本處理,無需轉義,而花括號也如此regexp

  • Try it: regexr.com/
  • Regexp : /\{\w+}\[hello-world]/
  • Text : {abc}[hello-world] hey! hey! hey!

(2) 再次匹配先前匹配的文本

若是須要匹配一個 yyyy-mm-dd 格式的日期,其中月份和日期都是年份的個十位

/\b\d\d(\d\d)-\1-\1\b/

反斜槓\1-9能夠獲得前面分組(\d\d)捕獲到的結果,若是是10-99呢?那就\10\99

  • Try it: regexr.com/
  • Regexp : /\b\d\d(\d\d)-\1-\1\b/
  • Text : 2008-08-08

(3) 單詞邊界

單詞邊界這個概念我開始比較抽象,也花了點時間去實踐究竟是啥,因此在這裏做爲一個案例來講說。

在單詞邊界匹配的位置,單詞字符後面或前面不與另外一個單詞字符直接相鄰。 不太明白,仍是看實例吧!

"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匹配的位置以下:

https://user-gold-cdn.xitu.io/2017/7/11/3b6b20924441295026cd34c12e2a210a
https://user-gold-cdn.xitu.io/2017/7/11/3b6b20924441295026cd34c12e2a210a

細心的你必定會發現數字的開始,小數點的左右都會有單詞邊界,這意味着單詞邊界不單單是英文字母,還包括數字。

\b屬於匹配位置的元字符,通常做佔位做用,而不被捕獲,同屬於匹配位置的還有匹配行起始位^和行結束位$

(4) 處理24小時制時間

24小時制能夠分爲三段:

  1. 00 - 09
  2. 10 - 19
  3. 20 - 23

先匹配第一階段: /[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]/

(5) 千分位

咱們在一些場景裏須要將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複製代碼

參考文獻:

  • 《精通正則表達式》
  • 《正則表達式經典實例》
相關文章
相關標籤/搜索