我们前两节课爬取珍爱网的时候,用到了很多正则表达式去匹配城市列表、城市、用户信息,其实除了正则表达式去匹配,还可以利用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("[email protected]")
if err != nil {
//....正则语法错误,需要处理错误
fmt.Println(err)
}
//[email protected]
fmt.Println(compile.FindString(text))
compile, err :=regexp.Compile("[email protected]")
函数返回一个正则表达式匹配器和错误,当参数正则表达式不符合正则语法时返回error,比如说regexp.Compile("[[email protected]")就会报错missing closing ]
一般正则表达式是用户输入的才需要处理错误,而自己写的一般是不会有错的,所以可以使用compile:= regexp.MustCompile("[email protected]"),如果语法错误,就会发生panic。
text1 := `my email is [email protected]
aa email is [email protected]
bb email is [email protected]
cc email is [email protected]
`
//如果要提取[email protected]中的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)
}
结果输出如下:
[[[email protected] aa qq com] [[email protected] aa gmail com] [[email protected] bb qq com] [[email protected] cc qq.com cn]]
[[email protected] aa qq com]
[[email protected] aa gmail com]
[[email protected] bb qq com]
[[email protected] 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("[email protected]"))
//用户名密码:
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
點擊查看更多內容
為 TA 點贊
評論
評論
共同學習,寫下你的評論
評論加載中...
作者其他優質文章
正在加載中
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦