[译]Go正则表达式示例

原文:Golang Regex Replace Example by Brad

在这篇文章中,我会介绍如何在Go语言中使用正则表达式。Go标准库本身就包含正则表达式库regexp

首先给读者朋友们道个歉。最近一个多月主要忙两件事,所以博客没有更新。一个是换工作的事情,国庆节从工作将近四年的微博辞职了,虽然离职了,但还是祝愿微博发展的越来越好,在新公司一直在忙啊忙的,没有多少时间博客了。二是在极客时间开辟了一个专栏,专门介绍Go并发编程的相关知识,这个也是拖了一年之久的一个计划,趁辞职终于实施了,专栏出来了,我也写伤了,所以也是一直没有更新博客的原因。今天趁出差,在酒店的房间了翻译一篇文章,作为博客的新的起点,大家继续关注,持续为大家分享更多的开发文章。

什么是正则表达式?

一个正则表达式(regex)是一个字符串,定义了一种搜索模式。你可以很容易的使用正则表达式进行搜索、替换、抽取、和模式匹配等操作,使用一行代码就可以干普通多行的事情。

Go标准库使用RE2语法,RE2语法也是Python、C和Perl使用的正则表达式语法,下面是一些可用的正则表达式的函数(Regexp还包含很多类似的方法,这几个是典型的函数):

接下来让我使用例子来介绍这些正则表达式方法。

MatchString – 正则表达式匹配

regexp.MatchString()用来匹配子字符串。下面这个例子是检查字符串是否已Golang开头。我们使用^来匹配字符串中以文本的开始。我们使用^Golang作为正则表达式进行匹配:

1
2
3
4
5
6
7
8
9
10
package main
import (
"fmt"
"regexp"
)
func main() {
str := "Golang regular expressions example"
match, err := regexp.MatchString(`^Golang`, str)
fmt.Println("Match: ", match, " Error: ", err)
}

输出:
如果在字符串中有子字符串匹配这个正则表达式,那么这段代码回返回true:

1
Match: true Error:

Compile 或者 MustCompile

Compile() 或者 MustCompile()创建一个编译好的正则表达式对象。假如正则表达式非法,那么Compile()方法回返回error,而MustCompile()编译非法正则表达式时不会返回error,而是回panic。如果你想要很好的性能,不要在使用的时候才调用Compile()临时进行编译,而是预先调用Compile()编译好正则表达式对象:

1
2
regexp1, err := regexp.Compile(<code>regexp</code>)
regexp2 := regexp.MustCompile(<code>regexp</code>)

FindString - 查找字符串

FindString()用来返回第一个匹配的结果。如果没有匹配的字符串,那么它回返回一个空的字符串,当然如果你的正则表达式就是要匹配空字符串的话,它也会返回空字符串。使用 FindStringIndex 或者 FindStringSubmatch可以区分这两种情况。下面是FindString()的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main
import (
"fmt"
"regexp"
)
func main() {
str := "Golang expressions example"
regexp,_ := regexp.Compile("Gola([a-z]+)g")
fmt.Println(regexp.FindString(str))
}

输出:

1
Golang

FindStringIndex - 得到匹配字符串的索引

FindStringIndex()可以得到匹配的字符串在整体字符串中的索引位置。如果没有匹配的字符串,它回返回nil值。

1
2
3
4
5
6
7
8
9
10
11
12
13
package main
import (
"fmt"
"regexp"
)
func main() {
str := "Golang regular expressions example"
regexp, err := regexp.Compile(`exp`)
match := regexp.FindStringIndex(str)
fmt.Println("Match: ", match, " Error: ", err)
}

输出:

1
Match: [15 18] Error:

FindStringSubmatch

FindStringSubmatch() 除了返回匹配的字符串外,还会返回子表达式的匹配项。
如果没有匹配项,则返回nil值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main
import (
"fmt"
"regexp"
)
func main() {
str := "Golang regular expressions example"
regexp, err := regexp.Compile(`p([a-z]+)e`)
match := regexp.FindStringSubmatch(str)
fmt.Println("Match: ", match, " Error: ", err)
}

输出:

1
Match: [pre r] Error:

FindAllString

FindString方法的All版本,它返回所有匹配的字符串的slice。如果返回nil值代表没有匹配的字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main
import (
"fmt"
"regexp"
)
func main() {
str := "Golang regular expressions example"
regexp, err := regexp.Compile(`p([a-z]+)e`)
match := regexp.FindAllString(str, 2)
fmt.Println("Match: ", match, " Error: ", err)
}

输出:

1
Match: [pre ple] Error:

ReplaceAllString

ReplaceAllString 用来替换所有匹配的字符串,返回一个源字符串的拷贝。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main
import (
"fmt"
"regexp"
)
func main() {
str := "Golang regular expressions example"
regexp, err := regexp.Compile(`examp([a-z]+)e`)
match := regexp.ReplaceAllString(str, "tutorial")
fmt.Println("Match: ", match, " Error: ", err)
}

输出:

1
Match: Golang regular expressions tutorial Error:

Find(All)?(String)?(Submatch)?(Index)?

正则表达式提供了16个类似的查找方法,格式为Find(All)?(String)?(Submatch)?(Index)?

  • 当方法名中有All的时候,它回继续查找非重叠的后续的字符串,返回slice
  • 当方法名中有String的时候,参数设计字符串,否则时byte slice
  • 当方法名中有Submatch的时候, 还会返回子表达式(capturing group)的匹配项
  • 当方法名中有Submatch的时候,