如何在Go语言中使用正则表达式
本篇文章给大家分享的是有关如何在Go语言中使用正则表达式,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。
正则表达式是一种进行模式匹配和文本操纵的功能强大的工具。正则表达式灵活、易用,按照它的语法规则,随需构造出的匹配模式就能够从原始文本中筛选出几乎任何你想要得到的字符组合。
准则
默认是最短匹配,只要字符串满足条件就返回。
如果没有匹配到,都是返回为nil。
如果需要做最长匹配,调用Longest()函数。
正则表达式功能:匹配(macth),查找(find)和替换(replace)。
存在长度选择的函数,传入<0的数字表示匹配全部。
使用regexp调用
Match,MatchReader和 MatchString
//判断b中是够包含pattern能够组成的任意字符串 funcMatch(patternstring,b[]byte)(matchedbool,errerror) //判断readerr中返回的字符串是否包含pattern能够组成的任意字符串 funcMatchReader(patternstring,rio.RuneReader)(matchedbool,errerror) //判断字符串s中是否包含pattern能够组成的任意字符串 funcMatchString(patternstring,sstring)(matchedbool,errerror)
Compile 和 MushCompile
func Compile(expr string) (*Regexp, error)func MustCompile(str string) *Regexp
Compile :返回Regexp 对象,方便调用指针函数。
MustCompile :同Compile,解析表达式失败,会panic。
在匹配文本时,该正则表达式会尽可能早的开始匹配,并且在匹配过程中选择回溯搜索到的第一个匹配结果。这种模式被称为leftmost-first ,另外一般情况下使用MustCompile 即可。
使用regexp.Regexp对象来调用
Find 和 FindAll
func (re *Regexp) Find(b []byte) []byte
func (re *Regexp) FindAll(b []byte, n int) [][]byte
Find返回保管正则表达式re在b中的最左侧的一个匹配结果的[]byte切片。如果没有匹配到,会返回nil,最多匹配一个。
re:=regexp.MustCompile(`foo.?`) fmt.Printf("%q\n",re.Find([]byte(`seafoodfool`)))
re:=regexp.MustCompile(`foo.?`) fmt.Printf("%q\n",re.FindAll([]byte(`seafoodfool`),-1))
FindAll 功能与Find 一样,只是返回全部满足条件的数据。
FindString 和 FindAllString
func (re *Regexp) FindString(s string) string
func (re *Regexp) FindAllString(s string, n int) []string
与Find 和FindAll 一样,只是针对字符串string操作。
FindIndex 和 FindAllIndex
func (re *Regexp) FindIndex(b []byte) (loc []int)
func (re *Regexp) FindAllIndex(b []byte, n int) [][]int
FindIndex , 返回b 中满足匹配字符串部分的起始位置,同样是**“leftmost-first”**原则,loc包含起止位置。如果没有找到,直接返回nil 。
FindAllIndex ,功能和FindIndex 保持一致,只是匹配多个,n 决定了匹配的位置。
FindStringIndex 和 FindAllStringIndex
func (re *Regexp) FindStringIndex(s string) (loc []int)
func (re *Regexp) FindAllStringIndex(s string, n int) [][]int
与FindIndex 和FindAllIndex 使用方式类似,只是针对的是字符串string。
FindStringSubmatch 和 FindAllStringSubmatch
func (re *Regexp) FindStringSubmatch(s string) []string
FindStringSubmatch :采用左匹配原则,最多匹配一个,如果没有的话,返回nil 。对于返回的[]string ,分别标示匹配的字符串,子串。
re:=regexp.MustCompile(`a(x*)b(y|z)c`) fmt.Printf("%q\n",re.FindStringSubmatch("-axxxbyc-")) fmt.Printf("%q\n",re.FindStringSubmatch("-abzc-"))
输出结果:
["axxxbyc" "xxx" "y"]["abzc" "" "z"]
func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string
和FindStringSubmatch 使用类似,只是能顾选择匹配的长度,-1 表示匹配到末尾。
re:=regexp.MustCompile(`a(x*)b`) fmt.Printf("%q\n",re.FindAllStringSubmatch("-ab-",-1)) fmt.Printf("%q\n",re.FindAllStringSubmatch("-axxb-",-1)) fmt.Printf("%q\n",re.FindAllStringSubmatch("-ab-axb-",-1)) fmt.Printf("%q\n",re.FindAllStringSubmatch("-axxb-ab-",-1))
输出结果:
[["ab" ""]][["axxb" "xx"]][["ab" ""] ["axb" "x"]][["axxb" "xx"] ["ab" ""]]
FindSubmatchIndex 和 FindAllSubmatchIndex
func (re *Regexp) FindSubmatchIndex(b []byte) []int
func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int 计算子串在源串中的位置,已经存在(x*) 等返回结果处理,如果没有返回nil 。
另外,index 返回为左闭右开 的模式,示例中的2,2 表示空字符串的意思。 并且,不会存在重合匹配的,比如说"-axxb-ab-"去匹配a(x*)b ,不会存在第一个a 和最后一个b 结合的情况,如果使用Longest 就会匹配最长的。
re:=regexp.MustCompile(`a(x*)b`) //Indices: //01234567012345678 //-ab-axb--axxb-ab- fmt.Println(re.FindAllStringSubmatchIndex("-ab-",-1)) fmt.Println(re.FindAllStringSubmatchIndex("-axxb-",-1)) fmt.Println(re.FindAllStringSubmatchIndex("-ab-axb-",-1)) fmt.Println(re.FindAllStringSubmatchIndex("-axxb-ab-",-1)) fmt.Println(re.FindAllStringSubmatchIndex("-foo-",-1))
输出结果:
[[1 3 2 2]] // 2 2 表示为空[[1 5 2 4]][[1 3 2 2] [4 7 5 6]][[1 5 2 4] [6 8 7 7]][]
FindStringSubmatchIndex和FindAllStringSubmatchIndex func(re*Regexp)FindStringSubmatchIndex(sstring)[]int func(re*Regexp)FindAllStringSubmatchIndex(sstring,nint)[][]int 和FindSubmatchIndex,FindAllSubmatchIndex保持一致。 Longest func(re*Regexp)Longest()获取最长匹配的满足条件的内容。 re:=regexp.MustCompile(`a(|b)`) fmt.Println(re.FindString("ab")) re.Longest() fmt.Println(re.FindString("ab"))
输出结果:
aab
下面这种情况不会最长匹配。
re:=regexp.MustCompile(`a(x*)b`) re.Longest() fmt.Println(re.FindString("-axxb-ab-"))//axxb,不会存在第一个a和最后一个b组合的过程。
Match,MatchString和MatchReader
func (re *Regexp) Match(b []byte) bool
func (re *Regexp) MatchString(s string) bool
func (re *Regexp) MatchReader(r io.RuneReader) bool
判断b ,s 和r 返回的数据是否满足正则表达式,返回true 或者false 。
NumSubexp
func (re *Regexp) NumSubexp() int
返回分组的数量。
re0:=regexp.MustCompile(`a.`) fmt.Printf("%d\n",re0.NumSubexp()) re:=regexp.MustCompile(`(.*)((a)b)(.*)a`) fmt.Println(re.NumSubexp())
输出结果:
04
ReplaceAll和ReplaceAllString func(re*Regexp)ReplaceAll(src,repl[]byte)[]byte func(re*Regexp)ReplaceAllString(src,replstring)string ReplaceAllString与ReplaceAll使用方式相同。 re:=regexp.MustCompile(`a(x*)b`) fmt.Printf("%s\n",re.ReplaceAll([]byte("-ab-axxb-"),[]byte("T"))) fmt.Printf("%s\n",re.ReplaceAll([]byte("-ab-axxb-"),[]byte("$1")))//$1表示匹配的第一个子串,这是ab的中间无字符串,所以$1为空,然后使用空去替换满足正则表达式的部分。 fmt.Printf("%s\n",re.ReplaceAll([]byte("-ab-axxb-"),[]byte("$1W")))//"$1W"等价与"$(1W)",值为空,将满足条件的部分完全替换为空。 fmt.Printf("%s\n",re.ReplaceAll([]byte("-ab-axxb-"),[]byte("${1}W")))//${1}匹配(x*),保留。输出-W-xxW-
输出结果:
-T-T---xx-----W-xxW-
s:="HelloWorld,123Go!" //定义一个正则表达式reg,匹配Hello或者Go reg:=regexp.MustCompile(`(Hell|G)o`) s2:="2019-12-01,test" //定义一个正则表达式reg2,匹配YYYY-MM-DD的日期格式 reg2:=regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`) //最简单的情况,用“T替换”"-ab-axxb-"中符合正则"a(x*)b"的部分 reg3:=regexp.MustCompile("a(x*)b") fmt.Println(re.ReplaceAllString("-ab-axxb-","T"))//-T-T- //${1}匹配"HelloWorld,123Go!"中符合正则`(Hell|G)`的部分并保留,去掉"Hello"与"Go"中的'o'并用"ddd"追加 rep1:="${1}ddd" fmt.Printf("%q\n",reg.ReplaceAllString(s,rep1))//HelldddWorld,123Gddd! //首先,"2019-12-01,test"中符合正则表达式`(\d{4})-(\d{2})-(\d{2})`的部分是"2019-12-01",将该部分匹配'(\d{4})'的'2019'保留,去掉剩余部分 rep2:="${1}" fmt.Printf("%q\n",reg2.ReplaceAllString(s2,rep2))//2019,test //首先,"2019-12-01,test"中符合正则表达式`(\d{4})-(\d{2})-(\d{2})`的部分是"2019-12-01",将该部分匹配'(\d{2})'的'12'保留,去掉剩余部分 rep3:="${2}" fmt.Printf("%q\n",reg2.ReplaceAllString(s2,rep3))//12,test //首先,"2019-12-01,test"中符合正则表达式`(\d{4})-(\d{2})-(\d{2})`的部分是"2019-12-01",将该部分匹配'(\d{2})'的'01'保留,去掉剩余部分,并追加"13:30:12" rep4:="${3}:13:30:12" fmt.Printf("%q\n",reg2.ReplaceAllString(s2,rep4))//01:13:30:12,test }
ReplaceAllFunc 和 ReplaceAllStringFunc
func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte
func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string
将匹配出来满足条件的[]byte 作为参数传入函数中。
re:=regexp.MustCompile(`[^aeiou]`) fmt.Println(re.ReplaceAllStringFunc("seafoodfool",strings.ToUpper))
两者使用方式类似。
ReplaceAllLiteral 和 ReplaceAllLiteralString
func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte
func (re *Regexp) ReplaceAllLiteralString(src, repl string) string
匹配字面常量,不转换。
re:=regexp.MustCompile(`a(x*)b`) fmt.Println(re.ReplaceAllLiteralString("-ab-axxb-","T")) fmt.Println(re.ReplaceAllLiteralString("-ab-axxb-","$1")) fmt.Println(re.ReplaceAllLiteralString("-ab-axxb-","${1}"))
输出结果:
-T-T--$1-$1--${1}-${1}-
关于$1 说明:
Expand 和 ExpandString
func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte
func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte
Expand返回新生成的将template添加到dst后面的切片。在添加时,Expand会将template中的变量替换为从src匹配的结果。match应该是被FindSubmatchIndex返回的匹配结果起止位置索引。(通常就是匹配src,除非你要将匹配得到的位置用于另一个[]byte)
在template参数里,一个变量表示为格式如:$name 或${name} 的字符串,其中name是长度>0的字母、数字和下划线的序列。一个单纯的数字字符名如$1会作为捕获分组的数字索引;其他的名字对应(?P...)语法产生的命名捕获分组的名字。超出范围的数字索引、索引对应的分组未匹配到文本、正则表达式中未出现的分组名,都会被替换为空切片。
$name格式的变量名,name会尽可能取最长序列:$1x 等价于${1x} 而非${1}x ,$10 等价于${10} 而非${1}0 。因此$name 适用在后跟空格/换行等字符的情况,${name} 适用所有情况。
如果要在输出中插入一个字面值'$' ,在template里可以使用$$ 。
其他示例
解析网址
flysnowRegexp:=regexp.MustCompile(`^http://www.flysnow.org/([\d]{4})/([\d]{2})/([\d]{2})/([\w-]+).html$`) params:=flysnowRegexp.FindStringSubmatch("http://www.flysnow.org/2018/01/20/golang-goquery-examples-selector.html") //返回[]string{}数据类型 for_,param:=rangeparams{ fmt.Println(param) }
输出结果:
http://www.flysnow.org/2018/01/20/golang-goquery-examples-selector.html20180120golang-goquery-examples-selector
以上就是如何在Go语言中使用正则表达式,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注恰卡编程网行业资讯频道。
推荐阅读
Go语言中的Goroutine和channel怎么使用
Go语言中的Goroutine和channel怎么使用这篇“Go语...
go语言中协程与线程的区别有哪些
go语言中协程与线程的区别有哪些这篇文章主要介绍“go语言中协程与...
go语言有哪些好处
go语言有哪些好处这篇文章主要介绍“go语言有哪些好处”的相关知识...
Go语言中转义符怎么使用
Go语言中转义符怎么使用这篇文章主要讲解了“Go语言中转义符怎么使...
go语言如何判断一个文件是否存在
go语言如何判断一个文件是否存在这篇文章主要介绍“go语言如何判断...
go语言中不定参数指的是什么
go语言中不定参数指的是什么这篇“go语言中不定参数指的是什么”文...
go语言空白标识符怎么使用
go语言空白标识符怎么使用这篇文章主要介绍了go语言空白标识符怎么...
go语言预定义标识符怎么使用
go语言预定义标识符怎么使用本文小编为大家详细介绍“go语言预定义...
go语言中join方法怎么使用
go语言中join方法怎么使用这篇“go语言中join方法怎么使用...
go语言字符串如何将小写转为大写
go语言字符串如何将小写转为大写这篇“go语言字符串如何将小写转为...