// 文件内容直接用字符串表示
usersStr := `
Alice 20 [email protected]
Bob 25 [email protected]
gerrylon 26 [email protected]
`
userRe := regexp.MustCompile(`(?P<name>[a-zA-Z]+)\s+(?P<age>\d+)\s+(?P<email>\w+@\w+(?:\.\w+)+)`)
// 这里要用FindAllStringSubmatch,找到所有的匹配
users := userRe.FindAllStringSubmatch(usersStr, -1)
groupNames := userRe.SubexpNames()
var result []map[string]string // slice of map
// 循环所有行
for _, user := range users {
m := make(map[string]string)
// 对每一行生成一个map
for j, name := range groupNames {
if j != 0 && name != "" {
m[name] = strings.TrimSpace(user[j])
}
}
result = append(result, m)
}
prettyResult, _ := json.MarshalIndent(result, "", " ")
fmt.Println(string(prettyResult))
封装正则分组匹配提取
/**
* Parses url with the given regular expression and returns the
* group values defined in the expression.
*
*/
func getParams(regEx, url string) (paramsMap map[string]string) {
var compRegEx = regexp.MustCompile(regEx)
match := compRegEx.FindStringSubmatch(url)
paramsMap = make(map[string]string)
for i, name := range compRegEx.SubexpNames() {
if i > 0 && i <= len(match) {
paramsMap[name] = match[i]
}
}
return paramsMap
}
使用
params := getParams(`(?P<Year>\d{4})-(?P<Month>\d{2})-(?P<Day>\d{2})`, `2015-05-27`)
fmt.Println(params)
map[Year:2015 Month:05 Day:27]
Go 正则的基本使用
- 判断是否匹配
package main
import(
"fmt"
"regexp"
)
func main() {
matched, err := regexp.MatchString("foo.*", "seafood")
fmt.Println(matched, err)
matched, err = regexp.MatchString("bar.*", "seafood")
fmt.Println(matched, err)
matched, err = regexp.MatchString("a(b", "seafood")
fmt.Println(matched, err)
}
// true <nil>
// false <nil>
// false error parsing regexp: missing closing ): `a(b`
- 通过正则获取内容
package main
import(
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile("a.")
fmt.Println(re.FindAllString("paranormal", -1)) //-1表示返回所有匹配的值,[ar an al]
fmt.Println(re.FindAllString("paranormal", 2)) //2表示返回2个匹配的值,[ar an]
fmt.Println(re.FindAllString("paranormal", 1)) //1表示返回1个匹配的值,[ar]
fmt.Println(re.FindAllString("paranormal", 0)) //0表示返回0个匹配的值,[]
fmt.Println(re.FindAllString("graal", -1)) //[aa]
fmt.Println(re.FindAllString("none", -1)) //[]
}
正则匹配字符
正则表达式中,“.”(点符号)匹配的是除了换行符“\n”以外的所有字符。但有时候我们需要匹配包括换行符在内的字符,经过一番搜索,发现了几种正则表达式匹配任意字符(包括换行符)的方法。
可以用 ([\s\S]*)
,也可以用 “([\d\D])”、“([\w\W])” 来匹配,就可以匹配包括换行符在内的任意字符。
下面是正则表达式元字符介绍
“^” :^会匹配行或者字符串的起始位置,有时还会匹配整个文档的起始位置。
“$” :$会匹配行或字符串的结尾
而且被匹配的字符必须是以This开头有空格也不行,必须以Regex结尾,也不能有空格与其它字符
“\b” :不会消耗任何字符只匹配一个位置,常用于匹配单词边界 如 我想从字符串中“This is Regex”匹配单独的单词 “is” 正则就要写成 “\bis\b”
“\d”: 匹配数字,
例如要匹配一个固定格式的电话号码以0开头前4位后7位,如0737-5686123 正则:^0\d\d\d-\d\d\d\d\d\d\d$ 这里只是为了介绍“\d”字符,实际上有更好的写法会在 下面介绍。
“\w”:匹配字母,数字,下划线。
例如我要匹配“a2345BCD__TTz” 正则:“\w+” 这里的“+”字符为一个量词指重复的次数,稍后会详细介绍。
“\s”:匹配空格
例如字符 “a b c” 正则:“\w\s\w\s\w” 一个字符后跟一个空格,如有字符间有多个空格直接把“\s” 写成 “\s+” 让空格重复
“.”:匹配除了换行符以外的任何字符
这个算是“\w”的加强版了“\w”不能匹配 空格 如果把字符串加上空格用“\w”就受限了,看下用 “.”是如何匹配字符“a23 4 5 B C D__TTz” 正则:“.+
正则在线工具
Demo 提取微信公众号封面和标题
func getParams(regEx, url string) (paramsMap map[string]string) {
var compRegEx = regexp.MustCompile(regEx)
match := compRegEx.FindStringSubmatch(url)
paramsMap = make(map[string]string)
for i, name := range compRegEx.SubexpNames() {
if i > 0 && i <= len(match) {
paramsMap[name] = match[i]
}
}
return paramsMap
}
func search(url string) map[string]string {
r := "var msg_title = '(?P<title>.+)'.html\\(false\\);[\\s\\S]*var cdn_url_1_1 = \"(?P<cover>http.+)\""
res, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
}
}(res.Body)
if res.StatusCode != 200 {
log.Fatalf("status code error: %d %s", res.StatusCode, res.Status)
}
bodyBytes, err := io.ReadAll(res.Body)
html := string(bodyBytes)
params := getParams(r, html)
fmt.Println(params)
return params
}