Go标准库的 regexp 包基于RE2引擎实现,语法与 Perl/Python 等类似,但支持 UTF-8,全程高效且线性时间复杂度。
1. 基础使用
编译正则(强烈推荐 pre-compile)
1 2 3 4 5
| re := regexp.MustCompile(`\d+`)
re, err := regexp.Compile(`\d+`) if err != nil { }
|
匹配
1 2 3 4 5 6 7 8
| matched := re.MatchString("123abc")
matched = re.Match([]byte("123abc"))
s := re.FindString("123abc456") b := re.Find([]byte("123abc456"))
|
查找所有匹配
1 2 3
| all := re.FindAllString("123abc456", -1) all = re.FindAllStringIndex("123abc456", -1)
|
子匹配(捕获组)
1 2 3 4
| re2 := regexp.MustCompile(`(\d+)(\w+)`) result := re2.FindStringSubmatch("123abc")
idx := re2.FindStringSubmatchIndex("123abc")
|
替换
1 2 3 4
| newStr := re.ReplaceAllString("123abc456", "NUM") newStr = re.ReplaceAllStringFunc("123abc456", func(s string) string { return "NUM_" + s })
|
分割
1
| parts := re.Split("123abc456", -1)
|
2. 正则表达式语法(RE2 语法)
字符匹配
| 符号 |
含义 |
示例 |
. |
任意字符(不含换行符) |
. |
[abc] |
字符类 |
[0-9] |
[^abc] |
否定字符类 |
[^0-9] |
\d |
数字(0-9) |
\d+ |
\w |
单词字符 |
\w+ |
\s |
空白字符 |
\s+ |
量词(重复)
| 符号 |
含义 |
示例 |
* |
0 次或多次 |
a* |
+ |
1 次或多次 |
a+ |
? |
0 次或 1 次 |
a? |
{n,m} |
至少 n 次至多 m 次 |
a{3,5} |
{n,} |
至少 n 次 |
a{3,} |
分组与锚点
():捕获组(子匹配)
(?:re):非捕获组
^:字符串开头
$:字符串结尾
\A:字符串开头
\z:字符串结尾(不包括换行符前)
其他高级
(?i):大小写不敏感
(?m):多行模式(^ $ 匹配行首尾)
(?s):. 匹配换行符
注意:Go 的 regexp 不支持 lookbehind (?<=...)、(?<!...)、回溯引用 \1 等 PCRE 特性。
3. 实战示例
邮箱校验
1 2
| re := regexp.MustCompile(`^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$`) ok := re.MatchString("user@example.com")
|
URL 校验
1
| re := regexp.MustCompile(`^(http|https)://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(/\S*)?$`)
|
提取所有数字
1 2
| re := regexp.MustCompile(`\d+`) nums := re.FindAllString("价格: 123元, 数量: 456", -1)
|
替换敏感信息(信用卡号)
1 2
| re := regexp.MustCompile(`\d{16}`) result := re.ReplaceAllString("卡号: 1234567890123456", "XXXX")
|
4. 性能与最佳实践
- 始终 pre-compile:
var re = regexp.MustCompile(...)
- 使用非捕获组:
(?:...) 减少开销
- 限制量词:
{1,100} 而非 {,}(避免指数级回溯)
- 小字符串:用
MatchString 或 FindString;大字符串用 FindAll + 索引
- 错误处理:
Compile 返回 error(推荐)