元字元
空白字元
| 字元 | 描述 |
| :-: | :-: |
| \f | 匹配一個換頁符 |
| \n | 匹配一個換行符 |
| \r | 匹配一個回車符 |
| \t | 匹配一個製表符 |
| \v | 匹配一個垂直製表符 |
表示位置的字元
| 字元 | 描述 |
| :-: | :-: |
| ^ | 匹配輸入字串開始的位置 |
| $ | 匹配輸入字串結尾的位置 |
常用
| 字元 | 描述 |
| :-: | :-: |
| \d | 匹配一個數字字元。等價於 [0-9] |
| \D | 匹配一個非數字字元。等價於 [^0-9] |
| \w | 匹配字母、數字、下劃線。等價於'[A-Za-z0-9]' |
| \W | 匹配非字母、數字、下劃線。等價於 '[^A-Za-z0-9]' |
| \s | 匹配任何空白字元,包括空格、製表符、換頁符 |
| \S | 匹配任何非空白字元。等價於 [^ \f\n\r\t\v] |
| . | 匹配除換行符(\n、\r)之外的任何單個字元。要匹配包括 '\n' 在內的任何字元,請使用像"(. |
| \b | 匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er' |
| \B | 與 \b 相反:er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er' |
簡單Demo
# 匹配以ing結尾的單詞
ing\b
# 匹配11位數的中國手機號
1\d\d\d\d\d\d\d\d\d\d
區間
| 字元 | 描述 |
| :-: | :-: |
| [0-9] | 匹配0-9之間的數字 |
| [A-Z] | 匹配A-Z之間的陣列,也可以組合 [A-Za-z0-9] |
限定符
| 字元 | 描述 |
| :-: | :-: |
| | 匹配前面的 子表示式 >=0次,例如,zo 能匹配 "z" 以及 "zoo"。 等價於{0,}|
| + | 匹配前面的 子表示式 >=1次,例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等價於 {1,} |
| ? | 匹配前面的 子表示式 0/1次,例如,"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等價於 {0,1} |
| {n} | n 是一個非負整數。匹配確定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的兩個 o |
| {n,} | n 是一個非負整數。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等價於 'o+'。'o{0,}' 則等價於 'o' |
| {n,m} | m 和 n 均為非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 將匹配 "fooooood" 中的前三個 o。'o{0,1}' 等價於 'o?'。請注意在逗號和兩個數之間不能有空格 |
- 上面學習了:區間、限定符,結合元字元,有了他們三種
-
# 匹配九位數的qq郵箱
[0-9]{9}@qq.com
# 身份證號
\d{17}[0-9Xx]|\d{15}
# ip地址
\d{0,3}.\d{0,3}.\d{0,3}.\d{0,3}
普通字元 & 轉義
# 例子
\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}
- @ 就是普通字元,標識必定會出現的內容。 比如:匹配域名 juejin.im,你完全可以用
https://juejin.im
- 但由於符號 /、.、(、) 等等在正則是特殊字元,所以需要用轉義符 \ 轉義
https:\/\/juejin\.im
接下來說一些正規表示式中的一些重要概念嘍
- 子表示式
-
用圓括號組成一個比較複雜的匹配模式,那麼一個圓括號的部分我們可以看作是一個子表示式。
- 舉例 var reg=/(\d)([a-z]*)/gi
- (\d)就是第一個子表示式
- ([a-z]) 是第二個子表示式
Golang 中使用
package main
import (
"fmt"
"regexp"
)
func main() {
// 檢查電話號碼是否匹配正規表示式
// regexp.Match 和 regexp.MatchString 沒什麼區別,只是接受的引數型別不同
phoneNumber := "0931-87562387"
fmt.Println(regexp.Match(`^\d{4}-\d{8}$`, []byte(phoneNumber))) // true <nil>
fmt.Println(regexp.MatchString(`^\d{4}-\d{8}$`, phoneNumber)) // true <nil>
text := "Hello 世界!123 Go."
// regexp.Compile, 建立正規表示式物件, 還有一個方法與它類似,
// regexp.MustCompile, 但在解析失敗的時候回panic,常用於全域性正則表達變數的安全初始化
reg, _ := regexp.Compile(`[a-z]+`) // 查詢連續的小寫字母
// regexp.Regexp.FindAll 於 FindAllString 類似
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["ello" "o"]
reg, _ = regexp.Compile(`[^a-z]+`) // 查詢連續的非小寫字母
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["H" " 世界!123 G" "."]
reg, _ = regexp.Compile(`\w+`) // 查詢連續的單詞字母
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello" "123" "Go"]
reg, _ = regexp.Compile(`[[:upper:]]+`) // 查詢連續的大寫字母
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["H" "G"]
reg, _ = regexp.Compile(`[[:^ascii:]]+`) // 查詢連續的非ascii字串
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["世界!"]
reg, _ = regexp.Compile(`[\pP]+`) // 查詢連續的標點符號
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["!" "."]
reg, _ = regexp.Compile(`[\PP]+`) // 查詢連續的非標點符號
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello 世界" "123 Go"]
reg, _ = regexp.Compile(`[\p{Han}]+`) // 查詢連續的漢字
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["世界"]
reg, _ = regexp.Compile(`Hello|Go`) // 查詢Hello或者Go
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello" "Go"]
reg, _ = regexp.Compile(`(?:Hell|G)o`) // 查詢Hello或者Go
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello" "Go"]
reg, _ = regexp.Compile(`^H.*\s`) // 查詢行首以 H 開頭,以空格結尾的字串
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello 世界!123 "]
reg, _ = regexp.Compile(`(?U)^H.*\s`) // 查詢行首以 H 開頭,以空格結尾的字串 非貪婪模式
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello "]
reg, _ = regexp.Compile(`(?i:^hello).*Go`) // 查詢以 hello 開頭(忽略大小寫),以 Go 結尾的字串
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello 世界!123 Go"]
reg, _ = regexp.Compile(`\QGo.\E`) // 查詢 Go.
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Go."]
reg, _ = regexp.Compile(`(?U)^.* `) // 查詢從行首開始,以空格結尾的字串(非貪婪模式)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello "]
reg, _ = regexp.Compile(` [^ ]*$`) // 查詢以空格開頭,到行尾結束,中間不包含空格字串
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // [" Go."]
reg, _ = regexp.Compile(`(?U)\b.+\b`) // 查詢“單詞邊界”之間的字串
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello" " 世界!" "123" " " "Go"]
reg, _ = regexp.Compile(`[^ ]{1,4}o`) // 查詢連續 1 次到 4 次的非空格字元,並以 o 結尾的字串
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello" "Go"]
reg, _ = regexp.Compile(`(Hell|G)o`) // 查詢 Hello 或 Go,替換為 Hellooo、Gooo
fmt.Printf("%q\n", reg.ReplaceAllString(text, "${1}ooo")) // "Hellooo 世界!123 Gooo."
reg, _ = regexp.Compile(`(Hello)(.*)(Go)`) // 交換Hello和Ho
fmt.Printf("%q\n", reg.ReplaceAllString(text, "$3$2$1")) // "Go 世界!123 Hello."
reg = regexp.MustCompile(`[\f\t\n\r\v\123\x7F\x{10FFFF}\\\^\$\.\*\+\?\{\}\(\)\[\]\|]`) // 特殊字元的查詢
fmt.Printf("%q\n", reg.ReplaceAllString("\f\t\n\r\v\123\x7F\U0010FFFF\\^$.*+?{}()[]|", "-"))
}