Golang
主页 > 脚本 > Golang >

go语言中regexp正则表达式的操作

2025-10-01 | 佚名 | 点击:

Go 语言的 regexp 包提供了对正则表达式的支持。
正则表达式(regex)是一种字符串搜索模式,用来检查一个字符串是否符合某种特定的模式,或从中提取符合某种模式的子字符串。

1.regexp包概述

regexp 包支持对字符串的匹配、搜索和替换。它基于 RE2 正则表达式引擎,性能优异,避免了回溯带来的性能瓶颈。
该包提供了多个函数来编译正则表达式并进行匹配、查找、替换等操作。

2. 常用函数

2.1regexp.Compile(pattern string) (*Regexp, error)

该函数用于编译正则表达式字符串 pattern,并返回一个 Regexp 类型对象。如果正则表达式无效,会返回一个错误。
示例:

1

2

3

4

5

r, err := regexp.Compile(`\d+`)  // 匹配一个或多个数字

if err != nil {

    fmt.Println("Error compiling regex:", err)

    return

}

2.2regexp.MustCompile(pattern string) *Regexp

该函数与 Compile 类似,不过如果正则表达式不合法,它会立即 panic。适合在启动时使用,确保正则表达式是合法的。
示例:

1

r := regexp.MustCompile(`\d+`)

2.3r.MatchString(s string) bool

该方法检查给定的字符串 s 是否匹配正则表达式。如果匹配,返回 true,否则返回 false。
示例:

1

2

3

r := regexp.MustCompile(`\d+`)

fmt.Println(r.MatchString("12345"))  // 输出:true

fmt.Println(r.MatchString("abc"))    // 输出:false

2.4r.FindString(s string) string

该方法查找字符串中第一个匹配正则表达式的子字符串并返回。如果没有找到匹配项,则返回空字符串。
示例:

1

2

r := regexp.MustCompile(`\d+`)

fmt.Println(r.FindString("abc 12345 xyz")) // 输出:12345

2.5r.FindAllString(s string, n int) []string

查找字符串中所有匹配正则表达式的子字符串,并返回一个字符串切片。如果 n 为 -1,则表示返回所有匹配的子串。
示例:

1

2

r := regexp.MustCompile(`\d+`)

fmt.Println(r.FindAllString("abc 123 4567 89", -1))  // 输出:[123 4567 89]

2.6r.ReplaceAllString(s string, repl string) string

该方法用于替换字符串中所有匹配正则表达式的子字符串。repl 是替换的文本。
示例:

1

2

3

r := regexp.MustCompile(`\d+`)

result := r.ReplaceAllString("abc 123 4567 xyz", "#")

fmt.Println(result) // 输出:abc # # xyz

2.7r.FindSubmatch(s string) [][]byte

查找第一个匹配的子字符串,并返回每个捕获组的内容(包括完整匹配)。返回的是一个二维字节切片,每个字节切片表示一个匹配项。
示例:

1

2

3

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

match := r.FindSubmatch([]byte("abc 123-4567"))

fmt.Println(match)  // 输出:[[123-4567 123 4567]]

2.8r.Split(s string, n int) []string

根据正则表达式分割字符串,返回一个字符串切片。n 参数表示最多分割的次数。
示例:

1

2

r := regexp.MustCompile(`\s+`)

fmt.Println(r.Split("this is a test", -1))  // 输出:[this is a test]

3. 正则表达式语法

Go 语言的 regexp 包使用的是 RE2 正则表达式引擎,它支持一些常见的正则表达式语法:

4. 示例

示例 1:检查字符串是否符合正则表达式

1

2

3

4

5

6

7

8

9

10

11

12

13

14

package main

 

import (

    "fmt"

    "regexp"

)

 

func main() {

    // 编译正则表达式

    r := regexp.MustCompile(`\d+`)

    // 检查字符串是否包含数字

    fmt.Println(r.MatchString("abc123"))  // 输出:true

    fmt.Println(r.MatchString("abc"))     // 输出:false

}

示例 2:提取数字

1

2

3

4

5

6

7

8

9

10

11

12

13

14

package main

 

import (

    "fmt"

    "regexp"

)

 

func main() {

    // 编译正则表达式

    r := regexp.MustCompile(`\d+`)

    // 查找字符串中的第一个数字

    result := r.FindString("abc 12345 xyz")

    fmt.Println(result)  // 输出:12345

}

示例 3:替换字符串中的数字

1

2

3

4

5

6

7

8

9

10

11

12

13

14

package main

 

import (

    "fmt"

    "regexp"

)

 

func main() {

    // 编译正则表达式

    r := regexp.MustCompile(`\d+`)

    // 替换数字为 #

    result := r.ReplaceAllString("abc 123 4567 xyz", "#")

    fmt.Println(result)  // 输出:abc # # xyz

}

示例 4:分割字符串

1

2

3

4

5

6

7

8

9

10

11

12

13

14

package main

 

import (

    "fmt"

    "regexp"

)

 

func main() {

    // 编译正则表达式

    r := regexp.MustCompile(`\s+`)

    // 按空白字符分割字符串

    result := r.Split("this is a test", -1)

    fmt.Println(result)  // 输出:[this is a test]

}

5. 性能与注意事项

总结

regexp 包是 Go 语言中一个强大的工具,用于进行字符串模式匹配和替换操作。
通过使用该包,你可以灵活地处理复杂的字符串匹配任务,并且可以高效地进行文本处理。

案例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

package _case

 

import (

    "fmt"

    "regexp"

)

 

func RegexpCase() {

    test1()

    fmt.Println("------------")

    test2()

}

 

func test2() {

    // 案例

    pattern := `^[a-z]+\[[0-9]+\]$`

    re := regexp.MustCompile(pattern)

    fmt.Println(re.MatchString("asdf[22114]"))

 

    // FindAll传入[]byte;

    // FindAllString传入string

    bytes := re.FindAll([]byte("haha[1234]"), -1)

    fmt.Println(string(bytes[0]))

 

    re = regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)

    str := "今天日期:2024-10-21"

    replaced := re.ReplaceAllString(str, "我日你妈的")

    fmt.Println(replaced)

}

 

// 常见的正则表达式字符及其含义

// 锚点字符:

//

// ^:匹配字符串的开始。例如,^abc 匹配以 "abc" 开头的字符串。

// $:匹配字符串的结束。例如,abc$ 匹配以 "abc" 结尾的字符串。

// 字符匹配:

//

// .(点号):匹配任意一个字符,除了换行符。例子:a.b 可以匹配 "a_b"、"a1b",但不能匹配 "ab"。

// [ ]:定义字符集合,匹配集合中的任意一个字符。例如,[abc] 匹配 "a"、"b" 或 "c"。

// [^ ]:排除字符集合,匹配集合外的任意字符。例如,[^abc] 匹配除 "a"、"b" 和 "c" 以外的任意字符。

// 量词:

//

// *:匹配前面的元素 0 次或多次。例如,a* 匹配空字符串、"a"、"aa" 等。

// +:匹配前面的元素 1 次或多次。例如,a+ 匹配 "a"、"aa"、"aaa" 等。

// ?:匹配前面的元素 0 次或 1 次。例如,a? 匹配空字符串或 "a"。

// {n}:匹配前面的元素恰好 n 次。例如,a{3} 匹配 "aaa"。

// {n,}:匹配前面的元素至少 n 次。例如,a{2,} 匹配 "aa"、"aaa"、"aaaa" 等。

// {n,m}:匹配前面的元素至少 n 次,但不超过 m 次。例如,a{2,4} 匹配 "aa"、"aaa" 或 "aaaa"。

// 字符类:

//

// \d:匹配任意数字,等同于 [0-9]。

// \D:匹配非数字字符,等同于 [^0-9]。

// \w:匹配字母、数字或下划线,等同于 [a-zA-Z0-9_]。

// \W:匹配非字母、数字或下划线字符,等同于 [^a-zA-Z0-9_]。

// \s:匹配任意空白字符(包括空格、制表符、换行符等)。

// \S:匹配任意非空白字符。

// 分组和选择:

//

// ( ):定义捕获组,匹配的内容可以在后续操作中引用。例如,(abc) 匹配 "abc"。

// |:逻辑或,表示左右两边任意一个匹配即可。例如,a|b 匹配 "a" 或 "b"。

// 反斜杠转义:

//

// \:反斜杠用于转义特殊字符。例如,\. 匹配字符 ".",而不是表示任意字符的点号。

// 特殊字符类:

//

// \b:匹配单词边界。例如,\bword\b 匹配完整的 "word",但不会匹配 "sword" 中的 "word"。

// \B:匹配非单词边界。

// 举例说明

// ^\d{3}-\d{2}-\d{4}$:匹配符合格式的社会保障号(比如 "123-45-6789")。

//

// ^:匹配字符串的开始。

// \d{3}:匹配 3 个数字。

// -:匹配字符 -。

// \d{2}:匹配 2 个数字。

// \d{4}:匹配 4 个数字。

// $:匹配字符串的结束。

// ([A-Z][a-z]+):匹配以大写字母开头的单词(如 "Apple")。

//

// [A-Z]:匹配一个大写字母。

// [a-z]+:匹配一个或多个小写字母。

// ( ):定义捕获组。

func test1() {

    // Compile解析并返回一个正则表达式。如果成功返回,该Regexp就可用于匹配文本。

    re := regexp.MustCompile(".com")

    // FindString

    fmt.Println(re.FindString("(cainiao.com)"))

    fmt.Println(re.FindString("(cainiao.dz)"))

    fmt.Println(re.FindString("(cainiao1.com1)"))

 

    // FindStringIndex return符合正则表达式的字符的索引,左闭右开

    fmt.Println(re.FindStringIndex("google.com"))

    fmt.Println(re.FindStringIndex("abc.org"))

    fmt.Println(re.FindStringIndex("fb.com"))

 

    // FindStringSubmatch 该方法返回具有最左边匹配项和匹配组的字符串。找不到返回空字符串

    // ([a-z]+)称为匹配组

    re1 := regexp.MustCompile("f([a-z]+)ing")

    re2 := regexp.MustCompile("f([a-z]+)ing")

    fmt.Println(re1.FindStringSubmatch("flying1"))

    fmt.Println(re1.FindStringSubmatch("abcfloatingxyz"))

    fmt.Println(re2.FindStringSubmatch("flying1"))

    fmt.Println(re2.FindStringSubmatch("abcfloatingxyz"))

 

    fmt.Println("-----------")

    pattern := "([a-z]+)"

    regex := regexp.MustCompile(pattern)

    // FindStringSubmatch 只会返回一个 包含的匹配结果,和一个 匹配组 合成的一个切片

    // len:2

    matches := regex.FindStringSubmatch("apple banana orange")

    fmt.Println(matches[0])

    fmt.Println(matches[1])

    //fmt.Println(matches[2])

    //fmt.Println(matches[3])

    // 如果想要匹配所有符合正则表达式的值,要用FindAllStringSubmatch

    // n为-1时,匹配所有符合条件的字符串,n不为-1时,表示只匹配n次

    // 会返回一个二维切片

    matches1 := regex.FindAllStringSubmatch("apple banana orange", -1)

    fmt.Println(matches1)

    // 遍历匹配结果

    for i, match := range matches1 {

        fmt.Printf("匹配 %d 结果:%s\n", i, match[0])

        fmt.Printf("捕获组 %d 结果:%s\n", i, match[1])

    }

 

    // 命名捕获组语法

    // (?P<name>pattern)

    // name:捕获组名称,pattern:捕获组模式

    pattern = "(?P<fruit>[a-z]+)"

    // 建立正则表达式

    re3 := regexp.MustCompile(pattern)

    // 匹配单个值

    matches = re3.FindStringSubmatch("apple banana orange")

    fruit := matches[re3.SubexpIndex("fruit")]

    fmt.Println(fruit)

    // 匹配多个值

    matches1 = re3.FindAllStringSubmatch("apple banana orange", -1)

    for i, match := range matches1 {

        fruit = match[re3.SubexpIndex("fruit")]

        fmt.Printf("匹配结果%d:%s\n", i, match[0])

        fmt.Printf("捕获组组%d:%s\n", i, fruit)

    }

 

    // regexp.Match() 判断在[]byte中能否找到给定正则表达式的值,返回bool和err

    // .*:表示任意数量的任意字符(包括 0 个字符),可以匹配任何字符,除了换行符

    // "^abc.*z$"含义:

    // 匹配以abc开头中间任意个数任意类型字符(除换行符外)以z结尾的字符串

    matched, err := regexp.Match("^abc.*z$", []byte("abcdeeffgz"))

    fmt.Println(matched, err)

    matched, err = regexp.Match("^abc.*z$", []byte("bcdefgz"))

    fmt.Println(matched, err)

 

    // regexp.MatchString()类似regexp.Match()不过他只传字符串,而Match只传[]byte

}

原文链接:
相关文章
最新更新