引入
处理字符串经常遇到”找一段符合某种规则的文本”——邮箱格式、日期提取、敏感词替换。strings 包只能做精确匹配,正则表达式才能描述复杂的文本模式。Go 的 regexp 包提供编译型正则,性能很好。
正文
定义
定义
正则表达式是一种用特殊语法描述文本模式的工具。Go 的
regexp包提供编译型正则,先Compile编译模式,再对字符串做匹配、查找、替换等操作。
语法
import "regexp"
re := regexp.MustCompile(`\d+`)
fmt.Println(re.MatchString("abc123")) // true例子
匹配
re := regexp.MustCompile(`^\d{4}-\d{2}-\d{2}$`)
fmt.Println(re.MatchString("2026-07-20")) // true
fmt.Println(re.MatchString("2026/07/20")) // falseMatchString 返回布尔值,^ 和 $ 分别锚定开头和结尾,确保整个字符串都符合模式。
查找
re := regexp.MustCompile(`\b\w+@\w+\.\w+\b`)
emails := re.FindAllString("联系 [email protected] 或 [email protected]", -1)
fmt.Println(emails) // [[email protected] [email protected]]FindAllString 返回所有匹配结果,-1 表示不限制数量。
分组提取
re := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)
match := re.FindStringSubmatch("日期: 2026-07-20")
fmt.Println(match[0]) // 2026-07-20(完整匹配)
fmt.Println(match[1]) // 2026(年)
fmt.Println(match[2]) // 07(月)
fmt.Println(match[3]) // 20(日)FindStringSubmatch 返回完整匹配加各分组捕获的内容。
命名分组
re := regexp.MustCompile(`(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})`)
match := re.FindStringSubmatch("2026-07-20")
names := re.SubexpNames()
result := map[string]string{}
for i, name := range names {
if i > 0 && name != "" {
result[name] = match[i]
}
}
fmt.Println(result) // map[day:20 month:07 year:2026]命名分组用 (?P<name>pattern) 语法,配合 SubexpNames() 提取成 map,可读性更好。
替换
re := regexp.MustCompile(`\d+`)
result := re.ReplaceAllString("第1名和第2名", "X")
fmt.Println(result) // 第X名和第X名ReplaceAllString 把所有匹配替换成指定字符串。
函数替换
re := regexp.MustCompile(`\d+`)
result := re.ReplaceAllStringFunc("价格: 100 和 200", func(s string) string {
n, _ := strconv.Atoi(s)
return fmt.Sprintf("%d", n*2)
})
fmt.Println(result) // 价格: 200 和 400ReplaceAllStringFunc 用函数动态生成替换内容,适合复杂替换逻辑。
编译复用
var emailRe = regexp.MustCompile(`[\w.]+@[\w.]+\.\w+`)
func isValidEmail(s string) bool {
return emailRe.MatchString(s)
}把编译好的正则存成包级变量,避免每次调用都重新编译。
常见写法
| 写法 | 说明 |
|---|---|
regexp.MustCompile(pattern) | 编译正则(失败时 panic) |
regexp.Compile(pattern) | 编译正则(返回 error) |
re.MatchString(s) | 判断字符串是否匹配 |
re.FindString(s) | 返回第一个匹配 |
re.FindAllString(s, n) | 返回前 n 个匹配(-1 全部) |
re.FindStringSubmatch(s) | 返回匹配 + 分组 |
re.ReplaceAllString(s, rep) | 替换所有匹配 |
re.ReplaceAllStringFunc(s, fn) | 函数替换 |
re.Split(s, n) | 按正则分割字符串 |
re.SubexpNames() | 获取分组名称 |
特点
- Go 正则是编译型的,
MustCompile一次编译反复使用 MustCompile编译失败直接 panic,适合包级初始化Compile返回 error,适合动态模式或需要错误处理的场景- 支持命名分组
(?P<name>pattern),提取更清晰 FindAllString(s, -1)的-1表示不限制数量- 把编译好的正则存为全局变量复用,避免重复编译
- Go 正则语法基于 RE2,不支持回溯(lookaround),但性能稳定
理解
正则表达式就是给文本匹配写了一套规则描述语言。Go 的 regexp 包用编译模式,先编译后使用,性能很好。MustCompile 适合全局变量,FindStringSubmatch 配合命名分组能干净地提取结构化数据。记住把编译结果缓存起来,别在循环里反复编译。
引出
正则表达式处理字符串很强大,但在并发和网络编程中,怎么控制操作的生命周期和取消?接下来看 Go 上下文,学习 context.Context 怎么管理超时、取消和请求级数据传递。