我們前兩節課爬取珍愛網的時候,用到了很多正則表達式去匹配城市列表、城市、用戶信息,其實除了正則表達式去匹配,還可以利用goquery和xpath第三方庫匹配有用信息。而我利用了更優雅的正則表達式匹配。下來大概介紹下正則表達式。
比如我們匹配城市列表的時候,會取匹配所有城市的url,如下:
可以看到圖片后是小寫字母加數字,那么就可以用以下方式提取:
<a href="(http://www.zhenai.com/zhenghun/[0-9a-z]+)"[^>]*>([^<]+)</a>
[0-9a-z]+表示匹配小寫字母或者數字至少一次,[>]*表示匹配非>的字符任意次,然后[<]+表示匹配非<字符至少一次。我們要取到城市的url和城市名,所以對進行了分組。
通過以下方式就可以拿到url和city
const (
cityListReg = `<a href="(http://www.zhenai.com/zhenghun/[0-9a-z]+)"[^>]*>([^<]+)</a>`
)
compile := regexp.MustCompile(cityListReg)
submatch := compile.FindAllSubmatch(contents, -1)
for _, m := range submatch {
fmt.Println("url:" , string(m[1]), "city:", string(m[2]))
}
匹配包含g g,且gg中間至少一個小寫字母:
//匹配包含g g,且gg中間至少一個小寫字母
match, _ := regexp.MatchString("g([a-z]+)g", "11golang11")
//true
fmt.Println(match)
上面我們直接使用了字符串匹配的正則表達式,但是對於其他的正則匹配任務,需要使用一個優化過的正則對象:
compile, err := regexp.Compile("smallsoup@gmail.com")
if err != nil {
//....正則語法錯誤,需要處理錯誤
fmt.Println(err)
}
//smallsoup@gmail.com
fmt.Println(compile.FindString(text))
compile, err :=regexp.Compile("smallsoup@gmail.com")
函數返回一個正則表達式匹配器和錯誤,當參數正則表達式不符合正則語法時返回error,比如說regexp.Compile("[smallsoup@gmail.com")就會報錯missing closing ]
一般正則表達式是用戶輸入的才需要處理錯誤,而自己寫的一般是不會有錯的,所以可以使用compile:= regexp.MustCompile("smallsoup@gmail.com"),如果語法錯誤,就會發生panic。
text1 := `my email is aa@qq.com
aa email is aa@gmail.com
bb email is bb@qq.com
cc email is cc@qq.com.cn
`
//如果要提取A@B.C中的A、B、C,需要用到正則表達式的提取功能。
comp := regexp.MustCompile(`([a-zA-Z0-9]+)@([a-zA-Z0-9.]+)\.([a-zA-Z0-9]+)`)
//利用自匹配獲取正則表達式里括號中的匹配內容
submatchs := comp.FindAllStringSubmatch(text1, -1)
//submatchs其實是一個二維數組
fmt.Println(submatchs)
//去除每個匹配,submatch其實還是個slice
for _, submatch := range submatchs {
fmt.Println(submatch)
}
結果輸出如下:
[[aa@qq.com aa qq com] [aa@gmail.com aa gmail com] [bb@qq.com bb qq com] [cc@qq.com.cn cc qq.com cn]]
[aa@qq.com aa qq com]
[aa@gmail.com aa gmail com]
[bb@qq.com bb qq com]
[cc@qq.com.cn cc qq.com cn]
r := regexp.MustCompile("p([a-z]+)ch")
fmt.Println(r) //----->p([a-z]+)ch
//regexp 包也可以用來替換部分字符串為其他值。
fmt.Println(r.ReplaceAllString("a peach", "<smallsoup>")) //----->a <smallsoup>
//Func 變量允許傳遞匹配內容到一個給定的函數中,
in := []byte("a smallsoup")
out := r.ReplaceAllFunc(in, bytes.ToUpper)
fmt.Println(string(out)) //----->a PEACH
/*#######################常見表達式###########################*/
// 查找漢字
testText := "Hello 你好嗎, I like golang!"
reg := regexp.MustCompile(`[\p{Han}]+`)
fmt.Println(reg.FindAllString(testText, -1)) // ----->[你好]
reg = regexp.MustCompile(`[\P{Han}]+`)
fmt.Println(reg.FindAllString(testText, -1)) // ----->["Hello " ", I li golang!"]
fmt.Printf("%q\n", reg.FindAllString(testText, -1)) // ----->["Hello " ", I lm golang!"]
//Email
reg = regexp.MustCompile(`\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*`)
fmt.Println(reg.MatchString("smallsoup@qq.com"))
//用戶名密碼:
reg = regexp.MustCompile(`[a-zA-Z]|\w{6,18}`)
fmt.Println(reg.MatchString("w_dy_246"))
運行結果如下:
p([a-z]+)ch
a <smallsoup>
a smallsoup
[你好嗎]
[Hello , I like golang!]
["Hello " ", I like golang!"]
true
true
Process finished with exit code 0
本公眾號免費提供csdn下載服務,海量IT學習資源,如果你准備入IT坑,勵志成為優秀的程序猿,那么這些資源很適合你,包括但不限於java、go、python、springcloud、elk、嵌入式 、大數據、面試資料、前端 等資源。同時我們組建了一個技術交流群,里面有很多大佬,會不定時分享技術文章,如果你想來一起學習提高,可以公眾號后台回復【2】,免費邀請加技術交流群互相學習提高,會不定期分享編程IT相關資源。
掃碼關注,精彩內容第一時間推給你