文章目录
-
- [一、Go 正则表达式概述](#一、Go 正则表达式概述)
-
- [1.1 标准库 `regexp`](#1.1 标准库
regexp
) - [1.2 使用建议](#1.2 使用建议)
- [1.1 标准库 `regexp`](#1.1 标准库
- 二、正则表达式的基本操作
-
- [2.1 编译正则表达式](#2.1 编译正则表达式)
- [2.2 案例:编译正则表达式](#2.2 案例:编译正则表达式)
- 三、正则表达式匹配操作
-
- [3.1 完全匹配](#3.1 完全匹配)
- [3.2 查找匹配](#3.2 查找匹配)
- [3.3 查找所有匹配](#3.3 查找所有匹配)
- 四、正则表达式分组和捕获
-
- [4.1 使用分组捕获](#4.1 使用分组捕获)
- 五、正则表达式替换操作
-
- [5.1 替换匹配的字符串](#5.1 替换匹配的字符串)
- [5.2 使用函数替换](#5.2 使用函数替换)
- 六、正则表达式分割字符串
- 七、正则表达式高级用法
-
- [7.1 贪婪与非贪婪匹配](#7.1 贪婪与非贪婪匹配)
一、Go 正则表达式概述
1.1 标准库 regexp
Go 的 regexp
语言通过标准库 regexp
提供了对正则表达式的支持,支持正则表达式的编译、匹配、查找、替换等操作,实现了正则表达式的搜索和替换操作。它使用 RE2 语法,与 Perl 和 Python 类似,但不支持所有特性(如反向引用)。regexp
包提供了两种主要接口:
Regexp
类型:表示编译后的正则表达式。- 一系列便利函数,如
MatchString
、FindString
、FindAllString
等。
1.2 使用建议
- 预编译正则表达式:如果正则表达式会被多次使用,建议预编译以提高性能。
- 错误处理 :使用
Compile
时检查错误,避免运行时 panic。 - 避免过度复杂:复杂的正则表达式难以维护,必要时拆分为多个简单正则。
- 合理使用分组:分组捕获可以提取关键信息,但要注意索引顺序。
- 注意性能:正则表达式匹配可能较慢,尤其在处理大文本时,应尽量优化。
二、正则表达式的基本操作
2.1 编译正则表达式
推荐使用 Compile
或 MustCompile
来编译正则表达式:
regexp.Compile(pattern)
:返回*Regexp
和error
,如果正则表达式不合法会返回错误。regexp.MustCompile(pattern)
:如果正则表达式不合法,会 panic,适用于已知合法的正则表达式。
2.2 案例:编译正则表达式
go
package main
import (
"fmt"
"regexp"
)
func main() {
// 使用 Compile,处理可能的错误
re, err := regexp.Compile(`\d+`)
if err != nil {
fmt.Println("正则表达式编译失败:", err)
return
}
fmt.Println("编译成功:", re)
// 使用 MustCompile,确定正则合法时使用
re2 := regexp.MustCompile(`[a-z]+`)
fmt.Println("MustCompile 成功:", re2)
}
三、正则表达式匹配操作
3.1 完全匹配
使用 MatchString
检查字符串是否完全匹配正则表达式。
】案例:MatchString
go
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`^go$`)
fmt.Println(re.MatchString("go")) // true
fmt.Println(re.MatchString("golang")) // false
}
3.2 查找匹配
查找第一个匹配:使用 FindString
查找第一个匹配的子串。案例:FindString
go
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`\d+`)
fmt.Println(re.FindString("abc123def")) // "123"
fmt.Println(re.FindString("abcdef")) // ""
}
3.3 查找所有匹配
使用 FindAllString
查找所有匹配的子串。案例:FindAllString
go
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`\d+`)
fmt.Println(re.FindAllString("abc123def456", -1)) // ["123", "456"]
fmt.Println(re.FindAllString("abc123def456", 1)) // ["123"]
}
四、正则表达式分组和捕获
4.1 使用分组捕获
使用 FindStringSubmatch
获取分组匹配结果。案例:分组捕获
go
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)
match := re.FindStringSubmatch("2025-09-09")
if match != nil {
fmt.Println("完整匹配:", match[0]) // 2025-09-09
fmt.Println("年份:", match[1]) // 2025
fmt.Println("月份:", match[2]) // 09
fmt.Println("日期:", match[3]) // 09
}
}
五、正则表达式替换操作
5.1 替换匹配的字符串
使用 ReplaceAllString
替换所有匹配的子串。案例:ReplaceAllString
go
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`\d+`)
result := re.ReplaceAllString("abc123def456", "数字")
fmt.Println(result) // "abc数字def数字"
}
5.2 使用函数替换
使用 ReplaceAllStringFunc
对每个匹配结果应用函数。案例:ReplaceAllStringFunc
go
package main
import (
"fmt"
"regexp"
"strconv"
)
func main() {
re := regexp.MustCompile(`\d+`)
result := re.ReplaceAllStringFunc("abc123def456", func(s string) string {
num, _ := strconv.Atoi(s)
return strconv.Itoa(num * 2)
})
fmt.Println(result) // "abc246def912"
}
六、正则表达式分割字符串
使用 Split
按正则表达式分割字符串。案例:Split
go
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`\s+`)
fmt.Println(re.Split("a b c d", -1)) // ["a", "b", "c", "d"]
}
七、正则表达式高级用法
7.1 贪婪与非贪婪匹配
Go 默认是贪婪匹配(尽可能多地匹配),可以使用 ?
转为非贪婪匹配。案例:贪婪与非贪婪
go
package main
import (
"fmt"
"regexp"
)
func main() {
reGreedy := regexp.MustCompile(`<.*>`)
reNonGreedy := regexp.MustCompile(`<.*?>`)
html := "<div>hello</div>"
fmt.Println(reGreedy.FindString(html)) // "<div>hello</div>"
fmt.Println(reNonGreedy.FindString(html)) // "<div>"
}
总结 :Go 的 regexp
包提供了强大的正则表达式支持。
- 支持编译、匹配、查找、替换、分割等操作。
- 使用分组可以提取关键信息。
- 贪婪与非贪婪匹配可以灵活控制匹配行为。
- 正则表达式虽然强大,但应合理使用,避免过度复杂。