Skip to content

reg

在 Go 中,regexp 包提供了正则表达式的功能,用于字符串匹配、搜索和替换等操作。它支持 Perl 风格的正则表达式,并通过简洁的 API 提供了强大的功能。


基本用法

1. 导入 regexp

需要先导入 regexp 包:

go
import "regexp"

2. 编译正则表达式

  • 使用 regexp.Compileregexp.MustCompile 编译正则表达式。
  • regexp.Compile 会返回一个错误(error),适用于动态正则。
  • regexp.MustCompile 会在编译失败时 panic,适用于静态正则。

3. 常用方法

以下是常用方法的说明和示例:

方法作用
MatchString判断字符串是否匹配
FindString返回第一个匹配的子字符串
FindAllString返回所有匹配的子字符串
FindStringIndex返回第一个匹配的起始和结束位置
FindAllStringIndex返回所有匹配的起始和结束位置
ReplaceAllString替换所有匹配的子字符串
Split按匹配结果分割字符串

示例代码

1. 判断字符串是否匹配

go
package main

import (
	"fmt"
	"regexp"
)

func main() {
	re := regexp.MustCompile(`^a\d+b$`) // 匹配以"a"开头,"b"结尾,中间是数字的字符串
	fmt.Println(re.MatchString("a123b")) // true
	fmt.Println(re.MatchString("a12c"))  // false
}

2. 查找字符串

go
package main

import (
	"fmt"
	"regexp"
)

func main() {
	re := regexp.MustCompile(`\d+`) // 匹配数字

	// 查找第一个匹配项
	fmt.Println(re.FindString("abc123def456")) // "123"

	// 查找所有匹配项
	fmt.Println(re.FindAllString("abc123def456", -1)) // ["123" "456"]

	// 查找第一个匹配项的起始和结束位置
	fmt.Println(re.FindStringIndex("abc123def456")) // [3 6]
}

3. 替换字符串

go
package main

import (
	"fmt"
	"regexp"
)

func main() {
	re := regexp.MustCompile(`\d+`) // 匹配数字
	str := "abc123def456"

	// 替换所有匹配项
	result := re.ReplaceAllString(str, "#")
	fmt.Println(result) // "abc#def#"
}

4. 分割字符串

go
package main

import (
	"fmt"
	"regexp"
)

func main() {
	re := regexp.MustCompile(`\s+`) // 匹配空白字符
	str := "Go   is  awesome"

	// 按空白字符分割字符串
	parts := re.Split(str, -1)
	fmt.Println(parts) // ["Go" "is" "awesome"]
}

5. 使用分组

分组可以捕获匹配的子表达式。

go
package main

import (
	"fmt"
	"regexp"
)

func main() {
	re := regexp.MustCompile(`(\w+)@(\w+\.\w+)`) // 匹配邮箱

	str := "Email: example@domain.com"
	matches := re.FindStringSubmatch(str)

	fmt.Println(matches) // ["example@domain.com" "example" "domain.com"]
}
  • matches[0] 是完整的匹配结果。
  • matches[1] 是第一个分组 (\w+) 的内容。
  • matches[2] 是第二个分组 (\w+\.\w+) 的内容。

6. 忽略大小写

使用修饰符 (?i) 来忽略大小写:

go
package main

import (
	"fmt"
	"regexp"
)

func main() {
	re := regexp.MustCompile(`(?i)hello`) // 忽略大小写匹配 "hello"
	fmt.Println(re.MatchString("HELLO")) // true
	fmt.Println(re.MatchString("Hello")) // true
}

注意事项

  1. 正则表达式的性能

    • 尽量避免复杂的正则,特别是大量分组和重复嵌套。
    • 如果需要高性能匹配,可以结合 strings 包的函数处理简单模式。
  2. 动态正则表达式

    • 如果正则是用户提供的,建议使用 regexp.Compile 进行错误处理。
  3. 使用原生替代方案

    • 如果操作简单,可以优先考虑 stringsstrconv 提供的功能,如 ContainsSplit 等。

正则表达式是强大的工具,但在 Go 中推荐根据场景使用正则或简单的字符串处理函数来获得更好的性能和可读性。