最容易理解的正規表示式筆記

蜻蜓隊長dragonfly429發表於2018-06-18

正規表示式

正則是‘某種模式去匹配一類字串的一中公式’,正則是獨立於語言存在的,java,php,js,py,linux都支援

閱讀本文的時候可以開啟正則線上測試工具練習

簡單正則

我們先看個簡單正則的例子:
/^\d{5,8}\w+$/i
正則由

  • 分隔符(/)
  • 表示式(^\d{5,8}\w+$)
  • 適配模式(i)

三部分組成,

表示式又由

  • 表示位置的符號(^ $)
  • 元字元(\d \w)
  • 量詞({5,8} +)

組成,所以我們需要知道每個部分都能怎麼寫,然後組合起來就ok了。

分隔符

分隔符可以是除了數字 字母 下劃線 反斜線以及空白符以外的任何字元,我們常用的有/ # ~ !等,其實正斜線可讀性不好,在分析html時還會跟結束標籤衝突,推薦用#;

位置

位置 說明
^ 匹配字串開始
$ 匹配字串結尾
\b 匹配單詞的邊界
\B 匹配單詞的非邊界

元字元

元字元 說明
. 任意字元,不含換行!
\w [a-z A-Z 0-9 _]
\s 空白符
\d [0-9]
--- ---
\S 非空白符
\W \w的補集
\D 非數字
--- ---
- 表示範圍
[] 表示括號中的任意一個字元
[^] 表示不是括號中的任意一個字元

量詞

量詞
* 匹配零次或多次
匹配零次或一次
+ 匹配一次或多次
{n} 匹配n次
{n,} 匹配至少n次
{n,m} 匹配n-m次

模式

模式
模式修飾 -
i 忽略大小寫
m 多文字
s 單文字
x 忽略空白

另外:

經驗之談
.* 表示任意字元,但是不包括換行,你可以先把字串處理一下,替換掉換行
[\s\S] 表示任意字元,包括換行

轉義:

當我們要表示的元字元跟正則語法裡使用的符號衝突時,就需要轉義 比如 \. \* \? \\ 如果有好多要一起轉義那可以用\Q....\E 中間的部分都會被轉義

正則其實不難,看完簡單正則,寫個匹配電話號碼什麼的都可以了。

正則進階

其實正則博大精深,簡單正則能處理的場景還是少,我們來學習一些高階的

分支 豎線

看例子吧
如果你要匹配cat hat fat,可以怎麼寫?答案是#^[chf]at$,
那我們再加一個flat呢?#^[chfl]at$#這麼寫肯定不行。
答案是#^(c|h|f|fl)at$#
括號裡面會當作一個整體來處理,豎線表示這幾個都可以選。

分組

三個重複的a可以用a{3}來表示,那按abc重複三次怎麼寫?
答案是(abc){3},括號裡就是分組,會被當做一個整體。 另外,括號還有另外一個做用,就是被括號裡面的規則匹配到的對應的字串會被存起來,我們可以用特定的語法讀取。

反向引用

如果要你匹配go go,hei hei,這樣的重複兩次的單詞,怎麼寫?
你可能想到(\w+){2},這是不對的,這樣第一組是第一個字母,第二組是剩下字母,
我們需要一個方法能夠獲取到第一個分組,這就是反向引用。
答案是\b(\w+)\b\s+\1\b,\1表示前面括號的內容。
還可以這麼寫\b(?<word>\w+)\b\s+\k<word>\b,看得出來就是給分組命名了。

其實這還是分組的延伸,我們可以寫好幾個括號,我們就可以提取到字串的特定的部分。

分組也叫捕獲,捕獲和讀取分組還有一些語法,我列一下

語法 說明
(exp) 匹配exp,並將捕獲的內容放到自動命名的分組裡,用\1\2來讀取
(?exp) 匹配exp,並將捕獲的內容放到自定義命名的分組裡,用\k來讀取
(?'name'exp) 同上
(?:exp) 匹配exp,但是不會捕獲的內容

環視

這個我沒有辦法用人話講明白,我就簡單列下語法,不說了。

語法 說明
(?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp後面的位置
(?!exp) 匹配後面不是exp的位置
(?<!exp) 匹配前面不是exp的位置

貪婪/懶惰匹配模式

請看題
匹配以a開頭以b結尾的字元,很好寫a.*b,我用用來匹配aabab時,結果是aabab。 為什麼不是ab或者aab呢?
因為正則預設是匹配儘可能多的字串,也就是貪婪模式。 我們這麼寫a.*?b,就能匹配到aab,在量詞後面加?,就是懶惰模式,儘可能少。 那為什麼不是ab?不是更懶?正則還有一條規則,最先匹配到的優先順序最高,aab比ab先匹配到。 ...

常用模式

就是在表示式結尾加一個符號,以表示有特殊的匹配模式

模式
模式修飾 -
i 忽略大小寫
m 多文字
s 單文字 點通號
U 懶惰模式
D 結尾模式
x 忽略空白

例子懶得舉了....自己搜尋吧

常用正則舉例

//手機號碼校驗
^1(3|5|8)\d{9}$
//email
^\w+([-_.]\w+)*@\w+([-_.]\w+)*.\w+([-.]\w+)*$
複製程式碼

參考


相關文章