学习路径
/
Go
Go
/
教学大纲
/
正则表达式
正则

正则表达式 属于 Go

1 个练习

关于 正则表达式

Go 的 regexp 包提供了对正则表达式的支持。

语法

所接受的正则表达式语法与 Perl、Python 及其他语言使用的通用语法相同。

搜索模式和输入文本都按 UTF-8 解释。

使用反引号(`)创建字符串时,反斜杠(\)没有任何特殊含义,也不会标记特殊字符的开头,比如制表符\t或换行符\n:

"\t\n" // regular string literal with 2 characters: a tab and a newline
`\t\n`// raw string literal with 4 characters: two backslashes, a 't', and an 'n'

因此,创建正则表达式时最好使用反引号,因为这样就不需要转义反斜杠:

"\\" // string with a single backslash
`\\` // string with 2 backslashes

编译模式:RegExp类型

要使用正则表达式,我们必须先编译字符串模式。 这里的编译指的是,把正则表达式的字符串模式转换成一种更易于处理的内部表示。 每个模式只需要编译一次,之后就可以多次使用编译后的正则表达式。 类型regexp.Regexp表示编译后的正则表达式。 我们可以使用函数regexp.Compile把字符串模式编译成regexp.Regexp。 如果编译失败,这个函数会返回nil和一个错误:

re, err := regexp.Compile(`(a|b)+`)
fmt.Println(re, err) // => (a|b)+ <nil>
re, err = regexp.Compile(`a|b)+`)
fmt.Println(re, err) // => <nil> error parsing regexp: unexpected ): `a|b)+`

函数MustCompile是Compile的一个方便的替代品:

re = regexp.MustCompile(`[a-z]+\d*`)

使用这个函数就不需要处理错误。

Caution

MustCompile should only be used when we know for sure the pattern does compile, as otherwise the program will panic.

正则表达式的方法

Regexp有 16 个方法可以匹配正则表达式并识别匹配到的文本。 这些方法的名称都能被下面这个正则表达式匹配:

Find(All)?(String)?(Submatch)?(Index)?
  • 如果含有All,该例程会依次匹配整个表达式的各个不重叠的匹配项。
  • 如果含有String,实参是字符串;否则是字节切片;返回值也会相应地调整。
  • 如果含有Submatch,返回值是一个切片,用来标识表达式中各个连续的子匹配。
  • 如果含有Index,匹配和子匹配用输入字符串中的字节下标对来标识。

此外还有用于以下操作的方法:

  • 用替换字符串替换正则表达式的匹配项,以及
  • 拆分由正则表达式分隔的字符串。

总的来说,regexp包定义了 40 多个函数和方法。 下面我们会演示其中几个方法的用法。 这些函数以及其他函数的详细信息,请参阅 API 文档。

MatchString示例

方法MatchString报告字符串中是否包含正则表达式的任何匹配项。

re = regexp.MustCompile(`[a-z]+\d*`)
b = re.MatchString("[a12]")       // => true
b = re.MatchString("12abc34(ef)") // => true
b = re.MatchString(" abc!")       // => true
b = re.MatchString("123 456")     // => false

FindString示例

方法FindString返回一个字符串,其中包含正则表达式最左边那个匹配项的文本。

re = regexp.MustCompile(`[a-z]+\d*`)
s = re.FindString("[a12]")       // => "a12"
s = re.FindString("12abc34(ef)") // => "abc34"
s = re.FindString(" abc!")       // => "abc"
s = re.FindString("123 456")     // => ""

FindStringSubmatch示例

方法FindStringSubmatch返回一个字符串切片,其中包含正则表达式最左边那个匹配项的文本,以及它的各个子表达式(如果有)的匹配文本。 可以用它来找出匹配捕获组的字符串。 返回值为nil表示没有匹配。

re = regexp.MustCompile(`[a-z]+(\d*)`)
sl = re.FindStringSubmatch("[a12]")       // => []string{"a12","12"}
sl = re.FindStringSubmatch("12abc34(ef)") // => []string{"abc34","34"}
sl = re.FindStringSubmatch(" abc!")       // => []string{"abc",""}
sl = re.FindStringSubmatch("123 456")     // => <nil>

ReplaceAllString示例

方法re.ReplaceAllString(src,repl)返回src的一个副本,并把正则表达式re的匹配项替换为替换字符串repl。

re = regexp.MustCompile(`[a-z]+\d*`)
s = re.ReplaceAllString("[a12]", "X")       // => "[X]"
s = re.ReplaceAllString("12abc34(ef)", "X") // => "12X(X)"
s = re.ReplaceAllString(" abc!", "X")       // => " X!"
s = re.ReplaceAllString("123 456", "X")     // => "123 456"

Split示例

方法re.Split(s,n)把文本s按该表达式切分成若干子串,并返回这些表达式匹配项之间的子串切片。 数量n决定最多返回多少个子串。 如果n<0,该方法返回所有子串。

re = regexp.MustCompile(`[a-z]+\d*`)
sl = re.Split("[a12]", -1)      // => []string{"[","]"}
sl = re.Split("12abc34(ef)", 2) // => []string{"12","(ef)"}
sl = re.Split(" abc!", -1)      // => []string{" ","!"}
sl = re.Split("123 456", -1)    // => []string{"123 456"}

性能

本包提供的 regexp 实现保证运行时间与输入大小成线性关系。

注意事项

regexp包实现的是 RE2 正则表达式(\C 除外)。 其语法与 PCRE(“Perl 兼容正则表达式”)大体兼容,但也有一些差异。 详情请参阅这篇文章中的“注意事项”部分。

通过 GitHub 编辑 该链接会在新窗口或标签页中打开

学习 正则表达式

练习已锁定

再解锁 2 个练习即可练习 正则表达式