golang 字符串查找

1. 概述
字符串查找是计算机编程中常见的操作之一。在处理字符串时,我们经常需要查找某个子串在给定字符串中的位置或出现的次数。在 Golang 中,有多种方法可以完成字符串查找的任务,本文将详细介绍这些方法。
2. strings 包中的函数
Golang 的标准库中提供了 strings 包,其中包含了一些常用的字符串处理方法,包括字符串查找。下面是 strings 包中一些常用的字符串查找函数:
Contains(s, substr string) bool:判断字符串s是否包含子串substr,返回一个布尔值。Count(s, substr string) int:计算子串substr在字符串s中出现的次数,返回一个整数。Index(s, substr string) int:返回子串substr在字符串s中首次出现的位置,如果不存在则返回 -1。LastIndex(s, substr string) int:返回子串substr在字符串s中最后一次出现的位置,如果不存在则返回 -1。IndexAny(s, chars string) int:返回字符串chars中任意字符第一次出现在字符串s中的位置,如果不存在则返回 -1。LastIndexAny(s, chars string) int:同IndexAny,只不过从字符串s的末尾开始查找。
以下是一个示例代码,演示了如何使用 strings 包中的函数进行字符串查找操作:
package main
import (
"fmt"
"strings"
)
func main() {
str := "Hello, world! Hello, Golang!"
// 判断字符串是否包含子串
fmt.Println(strings.Contains(str, "world")) // true
fmt.Println(strings.Contains(str, "China")) // false
// 计算子串在字符串中出现的次数
fmt.Println(strings.Count(str, "Hello")) // 2
fmt.Println(strings.Count(str, "Goodbye")) // 0
fmt.Println(strings.Count(str, "Hello, Golang")) // 1
// 查找子串的首次和最后一次出现位置
fmt.Println(strings.Index(str, "world")) // 7
fmt.Println(strings.Index(str, "China")) // -1
fmt.Println(strings.LastIndex(str, "Hello, Golang")) // 18
// 查找字符串中任意字符的首次和最后一次出现位置
fmt.Println(strings.IndexAny(str, "AEIOUaeiou")) // 1
fmt.Println(strings.LastIndexAny(str, "AEIOUaeiou")) // 23
fmt.Println(strings.IndexAny(str, "XYZxyz")) // -1
fmt.Println(strings.LastIndexAny(str, "XYZxyz")) // -1
}
运行上述代码,输出如下:
true
false
2
0
1
7
-1
18
1
23
-1
-1
3. strings 包中的更高级函数
除了上述常用函数外,strings 包中还提供了一些更高级的字符串查找函数,下面是一些示例:
ContainsAny(s, chars string) bool:判断字符串s是否包含字符串chars中的任意字符,返回一个布尔值。ContainsRune(s string, r rune) bool:判断字符串s是否包含指定的 Unicode 字符r,返回一个布尔值。Fields(s string) []string:拆分字符串s,返回一个字符串切片,其中元素是s中的字段(以空格分隔)。FieldsFunc(s string, f func(rune) bool) []string:自定义函数来拆分字符串s,返回一个字符串切片,其中元素是s中满足自定义函数条件的字段。Join(a []string, sep string) string:连接字符串切片a中的所有元素,并用sep分隔。Split(s, sep string) []string:将字符串s按照sep进行分割,返回一个字符串切片。
以下是一个使用这些高级函数的示例代码:
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
str := "Hello, world! 你好,世界!"
// 判断字符串是否包含任意字符
fmt.Println(strings.ContainsAny(str, "AEIOUaeiou")) // false
fmt.Println(strings.ContainsAny(str, "你好世界")) // true
// 判断字符串是否包含指定的 Unicode 字符
fmt.Println(strings.ContainsRune(str, 'H')) // true
fmt.Println(strings.ContainsRune(str, '好')) // true
fmt.Println(strings.ContainsRune(str, 'X')) // false
// 拆分字符串并连接字段
fields := strings.Fields(str)
fmt.Println(fields) // [Hello, world! 你好,世界!]
fmt.Println(strings.Join(fields, "-")) // Hello,-world!-你好,世界!
// 自定义函数拆分字符串
fieldsFunc := strings.FieldsFunc(str, func(r rune) bool {
return unicode.IsPunct(r) || unicode.IsSpace(r)
})
fmt.Println(fieldsFunc) // [Hello world 你好 世界]
fmt.Println(strings.Join(fieldsFunc, "-")) // Hello-world-你好-世界
// 分割字符串
split := strings.Split(str, "o")
fmt.Println(split) // [Hell w, rld! 你好,世界!]
}
运行上述代码,输出如下:
false
true
true
true
false
[Hello, world! 你好,世界!]
Hello,-world!-你好,世界!
[Hello world 你好 世界]
Hello-world-你好-世界
[Hell w,rld! 你好,世界!]
4. 正则表达式查找
如果需要更复杂的字符串查找操作,例如模式匹配、正则表达式等,可以使用 regexp 包。该包提供了正则表达式的功能,可以方便地进行字符串查找和替换。
以下是一个使用 regexp 包进行字符串查找和替换的示例代码:
package main
import (
"fmt"
"regexp"
)
func main() {
str := "Hello, 123 Golang! 456"
// 使用正则表达式查找数字
re := regexp.MustCompile(`\d+`)
fmt.Println(re.FindAllString(str, -1)) // [123 456]
// 使用正则表达式替换字符串
str2 := re.ReplaceAllString(str, "###")
fmt.Println(str2) // Hello, ### Golang! ###
}
运行上述代码,输出如下:
[123 456]
Hello, ### Golang! ###
上述代码中的正则表达式 \d+ 表示匹配一个或多个数字。FindAllString 方法返回一个包含所有匹配项的字符串切片。而 ReplaceAllString 方法会将字符串中所有匹配正则表达式的部分替换为指定的字符串。
极客笔记