正則表達式是一種進行模式匹配和文本操縱的復雜而又強大的工具。雖然正則表達式比純粹的文本匹配效率低,但是它卻更靈活。按照它的語法規則,隨需構造出的匹配模式就能夠從原始文本中篩選出幾乎任何你想要得到的字符組合。
Go語言通過regexp標准包為正則表達式提供了官方支持,如果你已經使用過其他編程語言提供的正則相關功能,那么你應該對Go語言版本的不會太陌生,但是它們之間也有一些小的差異,因為Go實現的是RE2標准,除了\C,詳細的語法描述參考:http://code.google.com/p/re2/wiki/Syntax
其實字符串處理我們可以使用strings包來進行搜索(Contains、Index)、替換(Replace)和解析(Split、Join)等操作,但是這些都是簡單的字符串操作,他們的搜索都是大小寫敏感,而且固定的字符串,如果我們需要匹配可變的那種就沒辦法實現了,當然如果strings包能解決你的問題,那么就盡量使用它來解決。因為他們足夠簡單、而且性能和可讀性都會比正則好。
一、正則匹配規則圖
參考官網: https://studygolang.com/pkgdoc
二、正則表達式
示例1: . 匹配任意類型
package main import ( "fmt" "regexp" ) func main() { buf := "abc azc a7c aac 888 a9c tac" //1) 解釋規則, 它會解析正則表達式,如果成功返回解釋器 reg1 := regexp.MustCompile(`a.c`) if reg1 == nil { fmt.Println("regexp err") return } //2) 根據規則提取關鍵信息 result1 := reg1.FindAllStringSubmatch(buf, -1) fmt.Println("result1 = ", result1) }
#執行結果:
result1 = [[abc] [azc] [a7c] [aac] [a9c]]
2、匹配a[0-9]c之間的數值
示例2:
package main import ( "fmt" "regexp" ) func main() { buf := "abc azc a7c aac 888 a9c tac" //1) 解釋規則, 它會解析正則表達式,如果成功返回解釋器 reg1 := regexp.MustCompile(`a[0-9]c`) if reg1 == nil { //解釋失敗,返回nil fmt.Println("regexp err") return } //2) 根據規則提取關鍵信息 result1 := reg1.FindAllStringSubmatch(buf, -1) fmt.Println("result1 = ", result1) }
執行結果:
result1 = [[a7c] [a9c]]
3、\d 匹配a[0-9]c之間的數值
示例3:
package main import ( "fmt" "regexp" ) func main() { buf := "abc azc a7c aac 888 a9c tac" //1) 解釋規則, 它會解析正則表達式,如果成功返回解釋器 reg1 := regexp.MustCompile(`a\dc`) if reg1 == nil { //解釋失敗,返回nil fmt.Println("regexp err") return } //2) 根據規則提取關鍵信息 result1 := reg1.FindAllStringSubmatch(buf, -1) fmt.Println("result1 = ", result1) }
執行結果:
result1 = [[a7c] [a9c]]
4、 +匹配前一個字符的1次或多次
示例:
package main import ( "fmt" "regexp" ) func main() { buf := "43.14 567 agsdg 1.23 7. 8.9 1sdljgl 6.66 7.8 " //解釋正則表達式, +匹配前一個字符的1次或多次 reg := regexp.MustCompile(`\d+\.\d+`) if reg == nil { fmt.Println("MustCompile err") return } //提取關鍵信息 //result := reg.FindAllString(buf, -1) result := reg.FindAllStringSubmatch(buf, -1) fmt.Println("result = ", result) }
執行結果:
result = [[43.14] [1.23] [8.9] [6.66] [7.8]]
5、過濾帶標簽或不帶標簽的
package main import ( "fmt" "regexp" ) func main() { //`` 原生字符串 buf := ` <!DOCTYPE html> <html lang="zh-CN"> <head> <title>Go語言標准庫文檔中文版 | Go語言中文網 | Golang中文社區 | Golang中國</title> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"> <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1"> <meta charset="utf-8"> <link rel="shortcut icon" href="/static/img/go.ico"> <link rel="apple-touch-icon" type="image/png" href="/static/img/logo2.png"> <meta name="author" content="polaris <polaris@studygolang.com>"> <meta name="keywords" content="中文, 文檔, 標准庫, Go語言,Golang,Go社區,Go中文社區,Golang中文社區,Go語言社區,Go語言學習,學習Go語言,Go語言學習園地,Golang 中國,Golang中國,Golang China, Go語言論壇, Go語言中文網"> <meta name="description" content="Go語言文檔中文版,Go語言中文網,中國 Golang 社區,Go語言學習園地,致力於構建完善的 Golang 中文社區,Go語言愛好者的學習家園。分享 Go 語言知識,交流使用經驗"> </head> <div>和愛好</div> <div>哈哈 你在嗎 不在 </div> <div>測試</div> <div>你過來啊</div> <frameset cols="15,85"> <frame src="/static/pkgdoc/i.html"> <frame name="main" src="/static/pkgdoc/main.html" tppabs="main.html" > <noframes> </noframes> </frameset> </html> ` //解釋正則表達式, +匹配前一個字符的1次或多次 //reg := regexp.MustCompile(`<div>(.*)</div>`) reg := regexp.MustCompile(`<div>(?s:(.*?))</div>`) if reg == nil { fmt.Println("MustCompile err") return } //提取關鍵信息 result := reg.FindAllStringSubmatch(buf, -1) //fmt.Println("result = ", result) //過濾<></> for _, text := range result { //過濾帶標簽的 //fmt.Println("text[0] = ", text[0]) //帶<></> //過濾不帶標簽的 fmt.Println("text[1] = ", text[1]) //不帶<></> } }
#執行結果:
過濾帶標簽的
text[0] = <div>和愛好</div> text[0] = <div>哈哈 你在嗎 不在 </div> text[0] = <div>測試</div> text[0] = <div>你過來啊</div>
//過濾不帶標簽的
text[1] = 和愛好 text[1] = 哈哈 你在嗎 不在 text[1] = 測試 text[1] = 你過來啊