37·标准库入门

字符串处理 strings

stringsbuilderreplacesplit

第37课 - 字符串处理 strings

1. 学习目标

完成本课学习后,你将能够:

  • 掌握 Go 标准库 strings 包的核心函数及其使用场景
  • 理解字符串不可变性的特点,并学会使用 strings.Builder 高效构建字符串
  • 熟练运用 SplitReplaceJoin 等函数处理常见字符串操作
  • 能够组合多个 strings 函数解决实际的文本处理问题

2. 核心概念

字符串在Go中的特性

Go 语言中的字符串是不可变的字节序列。这意味着一旦创建,字符串的内容就不能被修改。每次对字符串进行“修改”操作(如拼接),实际上都会创建一个新的字符串。

s := "Hello"
// 这种直接拼接方式效率较低,每次都会生成新字符串
s += " World"

strings.Builder:高效的字符串构建器

当你需要多次拼接字符串时,应使用 strings.Builder。它内部维护一个字节切片,避免了频繁创建新字符串的开销。

var builder strings.Builder
builder.WriteString("Hello")
builder.WriteString(" ")
builder.WriteString("World")
result := builder.String() // "Hello World"

核心字符串处理函数

  • Split:按分隔符切割字符串
  • Replace:替换字符串中的子串
  • Join:用分隔符连接字符串切片
  • Contains:检查是否包含子串
  • Index:查找子串的位置

3. 代码示例

package main

import (
	"fmt"
	"strings"
)

func main() {
	// 示例1:使用 strings.Builder 高效拼接
	var builder strings.Builder
	for i := 0; i < 1000; i++ {
		builder.WriteString("Hello")
		if i < 999 {
			builder.WriteString(", ")
		}
	}
	fmt.Println("Builder拼接结果长度:", builder.Len())
	fmt.Println("前20个字符:", builder.String()[:20])

	// 示例2:Split 和 Join 的使用
	csvData := "姓名,年龄,城市,职业"
	fields := strings.Split(csvData, ",")
	fmt.Println("分割后的字段:", fields)
	
	// 重新组装,用分号分隔
	joined := strings.Join(fields, "; ")
	fmt.Println("重新组装:", joined)

	// 示例3:Replace 的不同用法
	original := "Go语言是Go语言最好的语言"
	
	// 替换所有匹配项
	replaced1 := strings.Replace(original, "Go语言", "Python", -1) // -1 表示全部替换
	fmt.Println("全部替换:", replaced1)
	
	// 只替换前2个
	replaced2 := strings.Replace(original, "Go语言", "Python", 2)
	fmt.Println("替换前2个:", replaced2)

	// 示例4:其他常用函数
	text := "Hello, Go World! Go is awesome!"
	
	// 检查是否包含
	fmt.Println("包含'Go':", strings.Contains(text, "Go"))
	
	// 统计出现次数
	fmt.Println("'Go'出现次数:", strings.Count(text, "Go"))
	
	// 查找位置
	fmt.Println("第一个'Go'的位置:", strings.Index(text, "Go"))
	
	// 大小写转换
	fmt.Println("转小写:", strings.ToLower(text))
	fmt.Println("转大写:", strings.ToUpper(text))
	
	// 去除空白
	padded := "   Hello World   "
	fmt.Printf("去除空白: '%s'\n", strings.TrimSpace(padded))
}

4. 实践练习

练习1:字符串构建器基础

编写一个函数,接收一个字符串切片,使用 strings.Builder 将它们连接起来,每个字符串之间用 " | " 分隔。

func joinWithSeparator(strs []string) string {
    // 你的实现
}

// 测试数据
input := []string{"Go", "Python", "JavaScript", "Rust"}
// 预期输出: "Go | Python | JavaScript | Rust"

练习2:CSV数据处理

编写一个函数,处理格式为 "key1=value1,key2=value2,key3=value3" 的字符串,输出所有值用 " - " 连接的结果。

func extractValues(config string) string {
    // 你的实现
}

// 测试
config := "host=localhost,port=8080,user=admin"
// 预期输出: "localhost - 8080 - admin"

练习3:敏感词过滤

编写一个函数,将输入文本中的 "bad" 和 "ugly" 替换为 "***",同时忽略大小写。

func filterText(text string) string {
    // 提示:考虑 strings.ToLower 或 strings.Contains
    // 你的实现
}

// 测试
text := "This is a Bad example, very UGLY text"
// 预期输出: "This is a *** example, very *** text"

5. 常见错误

错误1:频繁使用 + 拼接字符串

// 错误做法:性能差
var result string
for i := 0; i < 10000; i++ {
    result += "a" // 每次都会创建新字符串
}

// 正确做法:使用 Builder
var builder strings.Builder
for i := 0; i < 10000; i++ {
    builder.WriteString("a")
}
result := builder.String()

错误2:Split 和 Join 参数理解错误

str := "a,,b,,c"
parts := strings.Split(str, ",")  // 结果是 ["a", "", "b", "", "c"],注意空字符串
joined := strings.Join(parts, "-") // 结果是 "a--b--c"

// 如果想去掉空值,需要先过滤

错误3:Replace 的替换次数参数

str := "aaa"
// 错误:想替换所有但只写了0
replaced := strings.Replace(str, "a", "b", 0) // 0表示不替换

// 正确:用-1表示全部替换
replaced := strings.Replace(str, "a", "b", -1)

6. 小结

  • 字符串不可变性:Go中字符串创建后不能修改,每次"修改"都会创建新字符串
  • 性能优化:大量字符串拼接时,使用 strings.Builder 而非 + 操作符
  • 核心函数掌握
    • Split/Join:字符串与切片的相互转换
    • Replace:字符串替换(注意替换次数参数)
    • Contains/Index:字符串查找
    • TrimSpace/ToLower/ToUpper:格式化处理
  • 最佳实践:根据实际需求选择合适的函数组合,注意函数的参数和返回值

记住:Go的 strings 包提供了丰富的字符串处理工具,熟练掌握它们能让你在处理文本数据时更加高效。下一课我们将学习 sort 包,了解如何对数据进行排序。

练习编辑器

go
Loading...

继续学习

完成本课后,建议继续学习下一课「排序与搜索 sort」 以巩固所学知识。