GO 语言正则表达式 regexp 包用法

正则表达式概述

正则表达式是一种进行模式匹配和文本操纵的复杂而又强大的工具。

Go 通过 regexp 包为正则表达式提供了官方支持,其采用 RE2 语法,除了\c、\C外,Go语言和 Perl、Python 等语言的正则基本一致。

正则表达式语法规则

正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")构成的文字序列,可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。

下面的表格中列举了构成正则表达式的一些语法规则及其含义。

1) 字符

一般字符 匹配自身 abc abc 
. 匹配任意除换行符"\n"外的字符, 在 DOTALL 模式中也能匹配换行符 a.c abc ;
\ 转义字符,使后一个字符改变原来的意思;
[...] 字符集(字符类),对应的位置可以是字符集中任意字符。
字符集中的字符可以逐个列出,也可以给出范围,如 [abc] 或 [a-c],
第一个字符如果是 ^ 则表示取反,如 [^abc] 表示除了abc之外的其他字符。 a[bcd]e abe 或 ace 或 ade 
\d 数字:[0-9] a\dc a1c 
\D 非数字:[^\d] a\Dc abc 
\s 空白字符:[<空格>\t\r\n\f\v] a\sc a c 
\S 非空白字符:[^\s] a\Sc abc 
\w 单词字符:[A-Za-z0-9] a\wc abc 
\W 非单词字符:[^\w] a\Wc a c 

2) 数量词(用在字符或 (...) 之后)

* 匹配前一个字符 0 或无限次 abc* ab 或 abccc 
+ 匹配前一个字符 1 次或无限次 abc+ abc 或 abccc 
? 匹配前一个字符 0 次或 1 次 abc? ab 或 abc 
{m} 匹配前一个字符 m 次 ab{2}c abbc 
{m,n} 匹配前一个字符 m 至 n 次,m 和 n 可以省略,若省略 m,则匹配 0 至 n 次;
若省略 n,则匹配 m 至无限次 ab{1,2}c abc 或 abbc 

3) 边界匹配

^ 匹配字符串开头,在多行模式中匹配每一行的开头 ^abc abc 
$ 匹配字符串末尾,在多行模式中匹配每一行的末尾 abc$ abc 
\A 仅匹配字符串开头 \Aabc abc 
\Z 仅匹配字符串末尾 abc\Z abc 
\b 匹配 \w 和 \W 之间 a\b!bc a!bc 
\B [^\b] a\Bbc abc 

4) 逻辑、分组

| 代表左右表达式任意匹配一个,优先匹配左边的表达式 abc|def abc 或 def 
(...) 括起来的表达式将作为分组,分组将作为一个整体,可以后接数量词 (abc){2} abcabc 
(?P<name>...) 分组,功能与 (...) 相同,但会指定一个额外的别名 (?P<id>abc){2} abcabc 
\<number> 引用编号为 <number> 的分组匹配到的字符串 (\d)abc\1 1abe1 或 5abc5 
(?P=name) 引用别名为 <name> 的分组匹配到的字符串 (?P<id>\d)abc(?P=id) 1abe1 或 5abc5 

5) 特殊构造(不作为分组)

(?:...) (…) 的不分组版本,用于使用 "|" 或后接数量词 (?:abc){2} abcabc 
(?iLmsux) iLmsux 中的每个字符代表一种匹配模式,只能用在正则表达式的开头,可选多个 (?i)abc AbC 
(?#...) # 后的内容将作为注释被忽略。 abc(?#comment)123  abc123 
(?=...) 之后的字符串内容需要匹配表达式才能成功匹配 a(?=\d) 后面是数字的 a 
(?!...) 之后的字符串内容需要不匹配表达式才能成功匹配 a(?!\d) 后面不是数字的 a 
(?<=...) 之前的字符串内容需要匹配表达式才能成功匹配 (?<=\d)a 前面是数字的a 
(?<!...) 之前的字符串内容需要不匹配表达式才能成功匹配 (?<!\d)a 前面不是数字的a 

Regexp 包的使用

下面通过几个示例来演示一下 regexp 包的使用。

package main

import (
	"fmt"
	"regexp"
)

func main() {
	str := "abcdefg13456abcdefg13456"
	reg := regexp.MustCompile("a.*3")
	// FindString
	res := reg.FindString(str)
	fmt.Printf("res: %v\n", res)
	// FindAllString
	resArray := reg.FindAllString(str, -1)
	fmt.Printf("res: %v\n", resArray)
	// 禁止贪婪匹配
	reg2 := regexp.MustCompile("(?U)a.*3")
	resArray = reg2.FindAllString(str, -1)
	fmt.Printf("res: %v\n", resArray)
	// 替换示例
	str = reg2.ReplaceAllString(str, "--")
	fmt.Printf("str: %v\n", str)
}