查看帮助文档:
go doc regexp/syntax
在线查看:
常用的查询方法
常用查询方法
FindAllStringFindStringFindStringSubmatchFindAllStringSubmatch
子项查询说明 FindStringSubmatch
注意点:
FindStringSubmatch
func TestFlag5(t *testing.T) {
str := `_A_123567abv` //要查找的字符串
re, _ := regexp.Compile("_\\w_(.*)") //匹配规则
fmt.Println(re.FindStringSubmatch(str)) //查询
}
输出: 第一个元素永远是全部内容,刚开始不习惯,后来发现还是挺好用的
[_A_123567abv 123567abv]
搜索结果中,第一个是正则中完全匹配到的内容。第二个开始才是想要获取的子项。
子项查询说明 FindAllStringSubmatch
()
//查询内容
data1 := "type Demo struct {
Name string `json:\"name\" form:\"name\" gorm:\"column:name;comment: \"`
Age int `json:\"age\" form:\"age\" gorm:\"column:age;comment: \"`
}"
//正则表达式:查询结构体字段、字段类型和json标签中的内容
grep, _ := regexp.Compile(`([\w]{1,})[ ]{1,}([\[\]\w]{2,})[ ]{1,}` + "`" + `(json):"([\w]{1,})[,]{0,}(\w{0,})\"` + ".*`")
//使用FindAllStringSubmatch函数查询
result := grep.FindAllStringSubmatch(*s.StructValue, -1)
输出结果:
[
[Name string `json:"name" form:"name" gorm:"column:name;comment: "` Name string json name ] [Age int `json:"age" form:"age" gorm:"column:age;comment: "` Age int json age ]
]
注意,在这里,每个匹配的搜索结果都单独放在一个切片中。
常见问题与注意事项
转义字符的使用
\w\w
grep, _ := regexp.Compile(`\w{1,}`)
\w\
grep, _ := regexp.Compile("\\w{1,}")
关于最多和最少匹配
python中,最小匹配是有函数可以调用的。而go的regexp模块没有最小匹配的函数。
如果要使用最小匹配,需要配合正则的语法,在文档中介绍在这里
重复:
x* 重复>=0次匹配x,越多越好(优先重复匹配x)
x+ 重复>=1次匹配x,越多越好(优先重复匹配x)
x? 0或1次匹配x,优先1次
x{n,m} n到m次匹配x,越多越好(优先重复匹配x)
x{n,} 重复>=n次匹配x,越多越好(优先重复匹配x)
x{n} 重复n次匹配x
x*? 重复>=0次匹配x,越少越好(优先跳出重复)
x+? 重复>=1次匹配x,越少越好(优先跳出重复)
x?? 0或1次匹配x,优先0次
x{n,m}? n到m次匹配x,越少越好(优先跳出重复)
x{n,}? 重复>=n次匹配x,越少越好(优先跳出重复)
x{n}? 重复n次匹配x
*+
str := `"老虎大王者荣耀超人"` //要查找的字符串
re := regexp.MustCompile("[\u4e00-\u9fa5]{1,3}") //匹配规则,匹配1到3个中文字符
fmt.Println(re.FindAllString(str, -1)) //查询
输出
[老虎大 王者荣 耀超人]
关于.*? 的坑
.*?
x*? 重复>=0次匹配x,越少越好(优先跳出重复)
.*?.
按照这种匹配原则,空字符串总是优先匹配到的,这样就导致了下面的问题:
func TestFlag5(t *testing.T) {
data := "你吃饭了吗"
grep, _ := regexp.Compile(".*?")
result := grep.FindAllString(data, -1)
t.Log(result)
}
输出结果是
structToJson_test.go:107: [ ]
它只匹配到了五个空字符串。
.*.*
func TestFlag6(t *testing.T) {
data1 := "你吃饭了吗"
grep, _ := regexp.Compile(".*")//.*?改成了 .*
result := grep.FindAllString(data1, -1)
t.Log(result)
}
输出
structToJson_test.go:107: [你吃饭了吗]
.*?
func TestFlag7(t *testing.T) {
str := `你吃饭了吗` //要查找的字符串
re, _ := regexp.Compile(".*?了吗") //.*?后面加几个字符串,开头加不加无所谓
t.Log(re.FindAllString(str, -1)) //查询
}
输出
[你吃饭了吗]
关于匹配中文字符的坑
匹配中文字符这里有个坑,如果匹配规则使用的是双引号,正常输入匹配规则即可
re := regexp.MustCompile("[\u4e00-\u9fa5]{1,}")//匹配规则,\u4e00-\u9fa5表示unicoce中的人一个中文字符
但是如果你使用反引号包裹上面的匹配规则,查询时会导致panic报错
re := regexp.MustCompile(`[\u4e00-\u9fa5]{1,}`)//错误示例
需要写一个双引号包裹的匹配规则,然后赋值粘贴进去,最后变成一串乱码,这才是正确的。
re := regexp.MustCompile(`[一-龥]{1,}`) //匹配规则