我们前两节课爬取珍爱网的时候,用到了很多正则表达式去匹配城市列表、城市、用户信息,其实除了正则表达式去匹配,还可以利用goquery和xpath第三方库匹配有用信息。而我利用了更优雅的正则表达式匹配。下来大概介绍下正则表达式。

 

 

比如我们匹配城市列表的时候,会取匹配所有城市的url,如下:

 

go语言正则表达式_正则表达式

 

可以看到图片后是小写字母加数字,那么就可以用以下方式提取:

 

<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@")

 if err != nil {
   //....正则语法错误,需要处理错误
   fmt.Println(err)
 }

 //smallsoup@
 fmt.Println(compile.FindString(text))

 

compile, err :=regexp.Compile("smallsoup@")

函数返回一个正则表达式匹配器和错误,当参数正则表达式不符合正则语法时返回error,比如说regexp.Compile("[smallsoup@")就会报错missing closing ]

一般正则表达式是用户输入的才需要处理错误,而自己写的一般是不会有错的,所以可以使用compile:= regexp.MustCompile("smallsoup@"),如果语法错误,就会发生panic。

 

text1 := `my email is aa@
  aa email is aa@
  bb email is bb@
  cc email is cc@.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@ aa qq com] [aa@ aa gmail com] [bb@ bb qq com] [cc@.cn cc  cn]]
[aa@ aa qq com]
[aa@ aa gmail com]
[bb@ bb qq com]
[cc@.cn cc 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@"))
 //用户名密码:
 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

 

go语言正则表达式_正则表达式_02

目前2000+人已关注加入我们

go语言正则表达式_正则表达式_03 go语言正则表达式_正则表达式_04 go语言正则表达式_正则表达式_05 go语言正则表达式_正则表达式_06 go语言正则表达式_正则表达式_07 go语言正则表达式_正则表达式_08 go语言正则表达式_正则表达式_09 go语言正则表达式_正则表达式_10

go语言正则表达式_正则表达式_11 go语言正则表达式_正则表达式_12 go语言正则表达式_正则表达式_13 go语言正则表达式_正则表达式_14 go语言正则表达式_正则表达式_15 go语言正则表达式_正则表达式_16 go语言正则表达式_正则表达式_17 go语言正则表达式_正则表达式_07

 

看完本文,如果您觉得有用,还烦请老铁动动手指关注一下