本文旨在用最通俗的語言講述最枯燥的基本知識。
1.元字元
2.重複限定符
3.分組
4.轉義
5.條件或
6.區間
正規表示式在幾乎所有語言中都可以使用,無論是前端的 JavaScript、還是後端的 Java、c#。他們都提供相應的介面 / 函式支援正規表示式。
但很神奇的是:無論你大學選擇哪一門計算機語言,都沒有關於正規表示式的課程給你修,在你學會正則之前,你只能看著那些正則大師們,寫了一串外星文似的字串,替代了你用一大篇幅的 if else 程式碼來做一些資料校驗。
下面,我嘗試用一種比較通俗點的方式講一下正則,讓你能在讀完之後,能自己寫出一些簡單的正則,再不濟,能看到別人寫的正則,那也不錯了。
元字元
萬物皆有緣,正則也是如此,元字元是構造正規表示式的一種基本元素。
我們先來記幾個常用的元字元:
元字元 | 說明 |
---|---|
. | 匹配除換行符以外的任意字元 |
w | 匹配字母或數字或下劃線或漢字 |
s | 匹配任意的空白符 |
d | 匹配數字 |
匹配單詞的開始或結束 | |
^ | 匹配字串的開始 |
$ | 匹配字串的結束 |
有了元字元之後,我們就可以利用這些元字元來寫一些簡單的正規表示式了,
比如:
匹配有abc開頭的字串:
abc或者^abc
匹配8位數字的QQ號碼:
^dddddddd$
匹配1開頭11位數字的手機號碼:
^1dddddddddd$
重複限定符
有了元字元就可以寫不少的正規表示式了,但細心的你們可能會發現:別人寫的正則簡潔明瞭,而我寫的正則是由一堆亂七八糟而且重複的元字元組成的。正則沒提供辦法處理這些重複的元字元嗎?
答案是有的!
為了處理這些重複問題,正規表示式中一些重複限定符,把重複部分用合適的限定符替代,下面我們來看一些限定符:
語法 | 說明 |
---|---|
* | 重複零次或更多次 |
+ | 重複一次或更多次 |
? | 重複零次或一次 |
{n} | 重複n次 |
{n,} | 重複n次或更多次 |
{n,m} | 重複n到m次 |
有了這些限定符之後,我們就可以對之前的正規表示式進行改造了,比如:
匹配8位數字的QQ號碼:
^d{8}$
匹配1開頭11位數字的手機號碼:
^1d{10}$
匹配銀行卡號是14~18位的數字:
^d{14,18}$
匹配以a開頭的,0個或多個b結尾的字串
^ab*$
分組
從上面的例子(4)中看到,限定符是作用在與他左邊最近的一個字元,那麼問題來了,如果我想要 ab 同時被限定那怎麼辦呢?
正規表示式中用小括號 () 來做分組,也就是括號中的內容作為一個整體。
因此當我們要匹配多個 ab 時,我們可以這樣。
^(ab)*
轉義
我們看到正規表示式用小括號來做分組,那麼問題來了:
如果要匹配的字串中本身就包含小括號,那是不是衝突?應該怎麼辦?
針對這種情況,正則提供了轉義的方式,也就是要把這些元字元、限定符或者關鍵字轉義成普通的字元,做法很簡答,就是在要轉義的字元前面加個斜槓,也就是即可。如:要匹配以 (ab) 開頭:
^((ab))*
條件或
回到我們剛才的手機號匹配,我們都知道:國內號碼都來自三大網,它們都有屬於自己的號段,比如聯通有 130/131/132/155/156/185/186/145/176 等號段,假如讓我們匹配一個聯通的號碼,那按照我們目前所學到的正則,應該無從下手的,因為這裡包含了一些並列的條件,也就是“或”,那麼在正則中是如何表示“或”的呢?
正則用符號 | 來表示或,也叫做分支條件,當滿足正則裡的分支條件的任何一種條件時,都會當成是匹配成功。
那麼我們就可以用或條件來處理這個問題:
^(130|131|132|155|156|185|186|145|176)d{8}$
區間
實際是有的。
正則提供一個元字元中括號 [] 來表示區間條件。
- 限定 0 到 9 可以寫成
[0-9]
- 限定 A-Z 寫成
[A-Z]
- 限定某些數字
[165]
那上面的正則我們還改成這樣:
^((13[0-2])|(15[56])|(18[5-6])|145|176)d{8}$
反義
前面說到元字元的都是要匹配什麼什麼,當然如果你想反著來,不想匹配某些字元,正則也提供了一些常用的反義元字元:
反義元字元 | 說明 |
---|---|
W | 匹配任意不是字母或數字或下劃線或漢字的字元 |
S | 匹配任意不是空白符的字元 |
D | 匹配任意非數字的字元 |
B | 匹配不是單詞的開始或結束的字元 |
[^x] | 匹配除了x以外的任意字元 |
[^axios] | 匹配除了axios這幾個字母以外的任意字元 |