当前位置:网站首页>golang中的正则表达式使用注意事项与技巧
golang中的正则表达式使用注意事项与技巧
2022-07-01 07:57:00 【dorlolo】
golang中的正则表达式使用注意事项与技巧
regexp模块
查看帮助文档:
命令行查看:go doc regexp/syntax
在线查看:
- 中文文档 :
菜鸟教程 介绍一些正则的方法比较详细
GO语言中文文档对一些难懂的基础语法做了解释,比官方文档更易懂 - 英文文档:
https://pkg.go.dev/regexp go标准库文档,有很多示例。
关于转义字符的使用
反引号中使用类似\w(\w代表0-9A-Za-z_)这样的语法不用做任何处理
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)) //查询
输出
[老虎大 王者荣 耀超人]
关于.*? 的坑
在javaScript和python等其它语言中,.*?表示查询所有任意的字符串。
而在golang中,文档中是这样说明的
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,}`) //匹配规则
基础查询函数的说明
常用的查询方法
FindAllString: 完整匹配,仅查询一次,查询到后就返回;FindString: 完整匹配,可指定查询数量(全部或多个);FindStringSubmatch:子项查询,获取查询条件中指定的内容。仅查询一次,查询到后就返回;FindAllStringSubmatch: 子项查询,获取查询条件中指定的内容。可指定查询数量(全部或多个)。
子项查询 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 ]
]
注意,在这里,每个匹配的搜索结果都单独放在一个切片中。
边栏推荐
- Latex table
- Gdip - hatchBrush图案表
- Day5: scanner object, next() and nextline(), sequential structure, selection structure, circular structure
- Significance and measures of source code encryption
- [MySQL learning notes 26] view
- AArdio - 【问题】bass库回调时内存增长的问题
- Office365 - how to use stream app to watch offline files at any time
- SharePoint - modify web application authentication using PowerShell
- 【mysql学习笔记25】sql语句优化
- Vhost kick & call principle
猜你喜欢
随机推荐
Gui Gui programming (XV) - use scale to control font size changes
Uni hot update
论文学习——水文时间序列相似性查询的分析与研究
Missing API interface actual development series (14): ID card real name authentication verification
軟鍵盤高度報錯
Scala语言学习-07-构造器
Tupu software has passed CMMI5 certification| High authority and high-level certification in the international software field
MATLAB之基础知识
How to get a SharePoint online site created using the office365 group template
php laravel微信支付
Lm08 mesh series mesh inversion (fine)
Vhost kick & call principle
postgresql源码学习(26)—— Windows vscode远程调试Linux上的postgresql
Aardio - 阴影渐变文字
Five combination boxing, solving six difficult problems on campus and escorting the construction of educational informatization
源代码加密的意义和措施
matlab保存DB4i深度相机图片
力扣每日一题-第31天-202.快乐数
【mysql学习笔记26】视图
Php laraver Wechat payment









