正则表达式 #

一、regexp包概述 #

regexp包实现正则表达式搜索。

二、基本用法 #

2.1 编译正则表达式 #

go
import "regexp"

re, err := regexp.Compile(`\d+`)
if err != nil {
    fmt.Println("正则表达式错误:", err)
}

re = regexp.MustCompile(`\d+`)  // panic if error

2.2 匹配检查 #

go
re := regexp.MustCompile(`\d+`)

fmt.Println(re.MatchString("123"))      // true
fmt.Println(re.MatchString("abc"))      // false
fmt.Println(re.Match([]byte("123")))    // true

三、查找操作 #

3.1 FindString #

查找第一个匹配:

go
re := regexp.MustCompile(`\d+`)

fmt.Println(re.FindString("abc123def456"))  // "123"

3.2 FindAllString #

查找所有匹配:

go
re := regexp.MustCompile(`\d+`)

matches := re.FindAllString("abc123def456", -1)
fmt.Println(matches)  // ["123", "456"]

第二个参数限制匹配数量,-1表示全部。

3.3 FindStringIndex #

查找匹配位置:

go
re := regexp.MustCompile(`\d+`)

loc := re.FindStringIndex("abc123def")
fmt.Println(loc)  // [3, 6]

3.4 FindAllStringIndex #

查找所有匹配位置:

go
re := regexp.MustCompile(`\d+`)

locs := re.FindAllStringIndex("abc123def456", -1)
fmt.Println(locs)  // [[3, 6], [9, 12]]

3.5 FindStringSubmatch #

查找子匹配:

go
re := regexp.MustCompile(`(\w+)@(\w+\.\w+)`)

match := re.FindStringSubmatch("email: test@example.com")
fmt.Println(match)      // ["test@example.com", "test", "example.com"]
fmt.Println(match[0])   // "test@example.com"
fmt.Println(match[1])   // "test"
fmt.Println(match[2])   // "example.com"

3.6 FindAllStringSubmatch #

查找所有子匹配:

go
re := regexp.MustCompile(`(\d+)-(\d+)`)

matches := re.FindAllStringSubmatch("1-2, 3-4, 5-6", -1)
fmt.Println(matches)
// [["1-2" "1" "2"] ["3-4" "3" "4"] ["5-6" "5" "6"]]

四、替换操作 #

4.1 ReplaceAllString #

替换所有匹配:

go
re := regexp.MustCompile(`\d+`)

result := re.ReplaceAllString("abc123def456", "X")
fmt.Println(result)  // "abcXdefX"

4.2 ReplaceAllStringFunc #

使用函数替换:

go
re := regexp.MustCompile(`\d+`)

result := re.ReplaceAllStringFunc("abc123def456", func(s string) string {
    n, _ := strconv.Atoi(s)
    return strconv.Itoa(n * 2)
})
fmt.Println(result)  // "abc246def912"

4.3 ReplaceAll #

字节切片替换:

go
re := regexp.MustCompile(`\d+`)

result := re.ReplaceAll([]byte("abc123"), []byte("X"))
fmt.Println(string(result))  // "abcX"

五、分割操作 #

5.1 Split #

go
re := regexp.MustCompile(`[,\s]+`)

parts := re.Split("a, b, c, d", -1)
fmt.Println(parts)  // ["a", "b", "c", "d"]

六、正则表达式语法 #

6.1 常用元字符 #

语法 说明
. 任意字符
^ 行首
$ 行尾
* 0次或多次
+ 1次或多次
? 0次或1次
n次
至少n次
n到m次

6.2 字符类 #

语法 说明
[abc] a或b或c
[^abc] 非a/b/c
[a-z] a到z
\d 数字
\D 非数字
\w 单词字符
\W 非单词字符
\s 空白字符
\S 非空白字符

6.3 分组 #

语法 说明
(…) 捕获组
(?:…) 非捕获组
(?P…) 命名捕获组

6.4 命名捕获组 #

go
re := regexp.MustCompile(`(?P<user>\w+)@(?P<domain>\w+\.\w+)`)

match := re.FindStringSubmatch("test@example.com")
fmt.Println(match)

for i, name := range re.SubexpNames() {
    if i > 0 {
        fmt.Printf("%s: %s\n", name, match[i])
    }
}

七、实际应用 #

7.1 验证邮箱 #

go
func isValidEmail(email string) bool {
    re := regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`)
    return re.MatchString(email)
}

7.2 验证手机号 #

go
func isValidPhone(phone string) bool {
    re := regexp.MustCompile(`^1[3-9]\d{9}$`)
    return re.MatchString(phone)
}

7.3 提取URL #

go
func extractURLs(text string) []string {
    re := regexp.MustCompile(`https?://[^\s]+`)
    return re.FindAllString(text, -1)
}

7.4 提取HTML标签内容 #

go
func extractTagContent(html, tag string) []string {
    re := regexp.MustCompile(`<` + tag + `>(.*?)</` + tag + `>`)
    matches := re.FindAllStringSubmatch(html, -1)
    var results []string
    for _, m := range matches {
        results = append(results, m[1])
    }
    return results
}

7.5 密码强度检查 #

go
func checkPasswordStrength(password string) bool {
    if len(password) < 8 {
        return false
    }
    
    hasUpper := regexp.MustCompile(`[A-Z]`).MatchString(password)
    hasLower := regexp.MustCompile(`[a-z]`).MatchString(password)
    hasDigit := regexp.MustCompile(`\d`).MatchString(password)
    hasSpecial := regexp.MustCompile(`[!@#$%^&*]`).MatchString(password)
    
    return hasUpper && hasLower && hasDigit && hasSpecial
}

7.6 清理字符串 #

go
func cleanString(s string) string {
    re := regexp.MustCompile(`\s+`)
    return strings.TrimSpace(re.ReplaceAllString(s, " "))
}

八、性能优化 #

8.1 预编译正则 #

go
var emailRegex = regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`)

func isValidEmail(email string) bool {
    return emailRegex.MatchString(email)
}

8.2 使用字面量 #

go
// 好
re := regexp.MustCompile(`\d+`)

// 避免
pattern := "\\d+"
re := regexp.MustCompile(pattern)

九、常见错误 #

9.1 转义问题 #

go
// 错误
re := regexp.MustCompile("\d+")  // \d被解释为转义

// 正确
re := regexp.MustCompile(`\d+`)  // 使用原始字符串

9.2 贪婪匹配 #

go
text := "<div>content1</div><div>content2</div>"

// 贪婪匹配
re := regexp.MustCompile(`<div>.*</div>`)
fmt.Println(re.FindString(text))  // 整个字符串

// 非贪婪匹配
re = regexp.MustCompile(`<div>.*?</div>`)
fmt.Println(re.FindString(text))  // <div>content1</div>

十、总结 #

regexp包常用函数:

函数 说明
Compile 编译正则表达式
MustCompile 编译(panic on error)
MatchString 检查是否匹配
FindString 查找第一个匹配
FindAllString 查找所有匹配
ReplaceAllString 替换所有匹配
Split 分割字符串

关键点:

  1. 预编译:多次使用时预编译正则表达式
  2. 原始字符串:使用反引号避免转义问题
  3. 命名捕获组:使用(?P…)命名
  4. 非贪婪匹配:使用*?和+?

准备好学习结构体了吗?让我们进入下一章!

最后更新:2026-03-26