Go基础:正则表达式 regexp 库详解

文章目录

一、Go 正则表达式概述

1.1 标准库 regexp

Go 的 regexp 语言通过标准库 regexp 提供了对正则表达式的支持,支持正则表达式的编译、匹配、查找、替换等操作,实现了正则表达式的搜索和替换操作。它使用 RE2 语法,与 Perl 和 Python 类似,但不支持所有特性(如反向引用)。regexp 包提供了两种主要接口:

  • Regexp 类型:表示编译后的正则表达式。
  • 一系列便利函数,如 MatchStringFindStringFindAllString 等。

1.2 使用建议

  1. 预编译正则表达式:如果正则表达式会被多次使用,建议预编译以提高性能。
  2. 错误处理 :使用 Compile 时检查错误,避免运行时 panic。
  3. 避免过度复杂:复杂的正则表达式难以维护,必要时拆分为多个简单正则。
  4. 合理使用分组:分组捕获可以提取关键信息,但要注意索引顺序。
  5. 注意性能:正则表达式匹配可能较慢,尤其在处理大文本时,应尽量优化。

二、正则表达式的基本操作

2.1 编译正则表达式

推荐使用 CompileMustCompile 来编译正则表达式:

  • regexp.Compile(pattern):返回 *Regexperror,如果正则表达式不合法会返回错误。
  • 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 包提供了强大的正则表达式支持。

  • 支持编译、匹配、查找、替换、分割等操作。
  • 使用分组可以提取关键信息。
  • 贪婪与非贪婪匹配可以灵活控制匹配行为。
  • 正则表达式虽然强大,但应合理使用,避免过度复杂。
相关推荐
快点好好学习吧7 小时前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q7 小时前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳07 小时前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾7 小时前
php 对接deepseek
android·开发语言·php
2601_949868367 小时前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
星火开发设计7 小时前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识
qq_177767377 小时前
React Native鸿蒙跨平台数据使用监控应用技术,通过setInterval每5秒更新一次数据使用情况和套餐使用情况,模拟了真实应用中的数据监控场景
开发语言·前端·javascript·react native·react.js·ecmascript·harmonyos
一匹电信狗7 小时前
【LeetCode_21】合并两个有序链表
c语言·开发语言·数据结构·c++·算法·leetcode·stl
橘子138 小时前
MySQL用户管理(十三)
数据库·mysql
Dxy12393102168 小时前
MySQL如何加唯一索引
android·数据库·mysql