Go正则表达式使用

【译文】原文地址
正则表达是一种常用于定义字符串搜索模式以及在软件中构建查找/替换等功能的常用方法。然而,现在框架和库比较多,处理正则表示方式迥异,有时也会让人奔溃。对于Golang,内置的regexp包包含了正则的所有使用方法并且非常健壮,使用起来很直观。

下面让我来看看regexp包的各种函数。

检查字符串的模式匹配

使用MatchString方法在字符串中查找匹配模式。第一个参数是正则表达式,第二个参数是输入字符串。

found, err := regexp.MatchString("g([a-z]+)ng", "golang")
fmt.Printf("found=%v, err=%v", found, err)

以上代码输出结果:

found=true, err=<nil>

它返回一个布尔值,表示查找的模式存在,如果regex编译失败,返回一个错误值。将无效的正则表达式传给MatchString方法会产生错误:

found, err := regexp.MatchString("g(-z]+ng  wrong regex", "golang")
fmt.Printf("found=%v, err=%v", found, err)

产生如下错误:

found=false, err=error parsing regexp: missing closing ): `g(-z]+ng  wrong regex`

复用正则表达式

使用内置的Compile函数将正则表达式存在变量中:

myRegex , err := regexp.Compile("g([a-z]+)ng")

Compile函数返回一个指向创建的RegExp对象的指针,而错误则表示正则表达式编译失败。myRegex变量现在可以用于任何操作。例如,我们在myRegex实例上使用MatchString函数:

found := myRegex.MatchString("golang")
fmt.Printf("found=%v", found)

输出结果为:

found=true

另一个选择是函数MustCompile。该函数只返回一个值丢弃了返回的errror。如果提供的字符串无法编译成regex,则MustCompile函数会导致程序的panic。、

reg := regexp.MustCompile("g([az]+ng") //Invalid regex
fmt.Println(reg.MatchString("golang"))

会生成如下信息:

panic: regexp: Compile(`g([az]+ng`): error parsing regexp: missing closing ): `g([az]+ng`

使用正则表达式进行单个匹配查询

使用FindString函数找到给定模式的第一个或者最左边的匹配项:

myRegex, _ := regexp.Compile("g([a-z]+)ng")
found := myRegex.FindString("The best language is golang")
fmt.Printf("found=%s", found)

输出为:

found=golang

如果没找到匹配的,结果是一个空字符串。

要获取第一个匹配字符串的索引,可以使用FindStringIndex方法。它返回一个包含两个原始的整数切片,表示正则表达式最左边匹配的位置起止点。

myRegex, _ := regexp.Compile("g([a-z]+)ng")
found := myRegex.FindStringIndex("We all like golang because it is cool")
fmt.Printf("start=%d, end=%d", found[0], found[1])

输出为:

start=12, end=18

如果没有匹配项,返回空切片。
FindStringSubMatch将提供给定模式的最左边匹配,以及该匹配中的子匹配:

myRegex, _ := regexp.Compile("g([a-z]+)ng")
found := myRegex.FindStringSubmatch("We all like golang because it is cool")
fmt.Printf("found  =%v", found)

输出为:

found  =[golang ola]

它返回了一个子字符串,在本例中包含两个子串,第一个元素是匹配g([a-z]+)ng得到的,第二个是内部匹配([a-z]+)结果。
类似FindString和FindStringIndex,FindStringSubMatch也有对应的FindStringSubmatchIndex。

myRegex, _ := regexp.Compile("g([a-z]+)ng")
found := myRegex.FindStringSubmatchIndex("We all like golang because it is cool")
fmt.Printf("found  =%v", found)

输出为:

found  =[12 18 13 16]

使用正则表达式进行多个结果查找

使用FindAllString查找给定字符串中所有匹配项。

myRegex, _ := regexp.Compile("g([a-z]+)ng")
found := myRegex.FindAllString("Can golang be called godlang?", -1)
fmt.Printf("found  =%v", found)

第二个参数指定所需的匹配数,-1表示匹配全部。输出结果为:

found  =[golang godlang]

FindString中讨论的所有变量也可以在FindAllString中使用,如下所示:

myRegex, _ := regexp.Compile("g([a-z]+)ng")
found1 := myRegex.FindAllString("Can golang be called godlang?", -1)
fmt.Printf("found1  =%v \n", found1)
found2 := myRegex.FindAllStringIndex("Can golang be called godlang?", -1)
fmt.Printf("found2  =%v \n", found2)
found3 := myRegex.FindAllStringSubmatch("Can golang be called godlang?", -1)
fmt.Printf("found3  =%v \n", found3)
found4 := myRegex.FindAllStringSubmatchIndex("Can golang be called godlang?", -1)
fmt.Printf("found4  =%v \n", found4)

对应输出结果:

found1  =[golang godlang] 
found2  =[[4 10] [21 28]] 
found3  =[[golang ola] [godlang odla]] 
found4  =[[4 10 5 8] [21 28 22 26]]

使用正则表达式修改字符串

使用ReplaceAllString函数将正则表达式的所有匹配项替换为不同的子字符串:

myRegex, _ := regexp.Compile("g([a-z]+)ng")
altered := myRegex.ReplaceAllString("Can golang be called godlang?", "python")
fmt.Println(altered)

输出为:

Can python be called python?

如您所见,所有的正则表达式匹配项都被字符串python替换。

推荐阅读更多精彩内容