go语言string操作

字符串类型string是一个不可变的字符序列,go从底层就采用UTF-8编码。
字符串在内存中是以byte数组存储的,如果是非ASCII字符的其他长度字符(如中文),每个rune就占多个byte。

字符串操作

  • 字符串定义
//转义字符\n \r \t \u \U分别表示换行,回车,制表符,Unicode字符
var str string = "测试转义字符: \t hello \u0067\U0000006F \n"
//使用反引号来定义原生字符串,无需转义原样输出
var str1 string = `使用反引号来定义原生字符串: hello 
go
你好
golang
`
fmt.Print(str, str1)
//一个ascii字符占1字节,一个中文字符占3字节。
fmt.Printf("字符串'你好,go'的长度:%d", len("你好,go"))

// 输出
测试转义字符:    hello go 
使用反引号来定义原生字符串:hello 
go
你好
golang
字符串'你好,go'的长度:9
  • 字符串比较
    字符串可以进行== != < <= > >=操作,这些操作都是按照底层byte数组顺序比较的。
s1, s2 := "你好,go", "你好,\u0067\U0000006F"
fmt.Println("s1 == s2? ", s1 == s2)
//输出:true
  • 字符串长度
fmt.Printf("内存长度:%d\n", len("你好,go")) //输出 9
fmt.Printf("rune长度:%d\n", utf8.RuneCountInString("你好,go")) //输出 5
  • 字符访问
fmt.Printf("字符串'你好,go'的第8个byte为:%c\n", "你好,go"[7]) //输出: g
//取rune,先将string转为rune数组,在按索引取
fmt.Printf("字符串'你好,go'的第2个rune为:%v\n", string([]rune("你好,go")[1])) //输出:好
  • 字符串拼接
    字符串拼接是将两个字符串拼接在一起,产生一个新的字符串并返回,注意字符串本身是不可变的
    有三种方式进行拼接:
//方法一:使用+拼接,效率相对较低,适用于少量字符串拼接
fmt.Print("hello " + " go" + "\n")
//方法二:使用bytes.Buffer拼接,效率高,节省内存
var stringBuilder bytes.Buffer
stringBuilder.WriteString("你好")
stringBuilder.WriteString("go")
fmt.Println(stringBuilder.String())
//方法三:使用fmt.Sprintf
fmt.Println(fmt.Sprintf("%s %s", "你好,", "go"))
  • 字符串遍历
    对于ASCII序列,使用for或for…range遍历都可以,对于非ASCII的Unicode使用for…range循环遍历。
s3 := "hello,go"
s4 := "你好,go"
//遍历byte序列,对于ASCII序列,这样遍历与预期一致
fmt.Print("遍历byte序列:")
for i := 0; i < len(s3); i++ {
	fmt.Printf("%c\t", s3[i])
}
fmt.Printf("\n%s", "遍历rune序列:")
//遍历rune序列,对于非ASCII遍历,需要使用这种方式遍历
//这里index返回的是rune字符第一个byte的index
for index, c := range s4 {
	fmt.Printf("s4[%d]=%c\t", index, c)
}
fmt.Println()
  • 子串查找
//子串查找
fmt.Printf("第一个lo的索引:%d,", strings.Index("hello hello go", "lo"))   //输出 3
fmt.Printf("截取第一个lo之前的子串:%s, ", s5[:strings.Index(s5, "lo")]) //输出 hel
fmt.Printf("最后一个lo的索引:%d", strings.LastIndex("hello hello go", "lo"))  //输出9

练习1 字符串修改

由于string类型变量是一个不可变的字符序列,如果要修改字符串,需要将其强制转换为[ ]byte,修改之后再赋值会原来的变量。

//修改字符串,将s5的第一个hello改成xxxxx
bytes := []byte(s5)
for i := 0; i < 5; i++ {
	bytes[i] = 'x'
}
s5 = string(bytes)
fmt.Println(s5)

练习2 字符串替换

//将"hello go,我正在学习"中的"go"替换为"world"
s6 := "hello go,我正在学习"
src := "go"
target := "world"

var stringBuilder1 bytes.Buffer
index := strings.Index(s6, src)
stringBuilder1.WriteString(s6[:index])
stringBuilder1.WriteString(target)
stringBuilder1.WriteString(s6[index+len(src):])
fmt.Println(stringBuilder1.String())

总结

主要介绍了字符串相关操作。

完整示例代码

package main

import (
	"bytes"
	"fmt"
	"strings"
	"unicode/utf8"
)

func main() {
	//string使用,转义字符\n \r \t \u \U分别表示换行,回车,制表符,Unicode字符
	var str string = "测试转义字符: \t 你好,\u0067\U0000006F\n"
	//使用反引号来定义原生字符串,无需转义原样输出
	var str1 string = `使用反引号来定义原生字符串: 你好, 
go
`
	fmt.Print(str, str1)

	//字符串比较
	s1, s2 := "你好,go", "你好,\u0067\U0000006F"
	fmt.Println("s1 == s2? ", s1 == s2)

	//一个ascii字符占1字节,一个中文字符占3字节。
	fmt.Printf("字符串'你好,go'的内存长度:%d\n", len("你好,go"))
	fmt.Printf("字符串'你好,go'的rune长度:%dv\n", utf8.RuneCountInString("你好,go"))

	//字符访问
	fmt.Printf("字符串'你好,go'的第8个byte为:%c\n", "你好,go"[7])
	fmt.Printf("字符串'你好,go'的第2个rune为:%v\n", string([]rune("你好,go")[1]))

	//字符串拼接
	//方法一:使用+拼接,效率相对较低,适用于少量字符串拼接
	fmt.Print("hello " + " go" + "\n")
	//方法二:使用bytes.Buffer拼接,效率高,节省内存
	var stringBuilder bytes.Buffer
	stringBuilder.WriteString("你好")
	stringBuilder.WriteString("go")
	fmt.Println(stringBuilder.String())
	//方法三:使用fmt.Sprintf
	fmt.Println(fmt.Sprintf("%s %s", "你好,", "go"))

	//遍历
	s3 := "hello,go"
	s4 := "你好,go"
	//遍历byte序列,对于ASCII序列,这样遍历与预期一致
	fmt.Print("遍历byte序列:")
	for i := 0; i < len(s3); i++ {
		fmt.Printf("%c\t", s3[i])
	}
	fmt.Printf("\n%s", "遍历rune序列:")
	//遍历rune序列,对于非ASCII遍历,需要使用这种方式遍历
	//这里index返回的是rune字符第一个byte的index
	for index, c := range s4 {
		fmt.Printf("s4[%d]=%c\t", index, c)
	}
	fmt.Println()

	//子串查找
	s5 := "hello hello go"
	fmt.Printf("第一个lo的索引:%d, ", strings.Index(s5, "lo"))
	fmt.Printf("截取第一个lo之前的子串:%s, ", s5[:strings.Index(s5, "lo")])
	fmt.Printf("最后一个lo的索引:%d", strings.LastIndex(s5, "lo"))

}

输出

测试转义字符:    你好,go
使用反引号来定义原生字符串: 你好, 
go
s1 == s2?  true
字符串'你好,go'的内存长度:9
字符串'你好,go'的rune长度:5v
字符串'你好,go'的第8个byte为:g
字符串'你好,go'的第2个rune为:好
hello  go
你好go
你好, go
遍历byte序列:h  e       l       l       o       ,       g       o
遍历rune序列:s4[0]=你   s4[3]=好        s4[6]=, s4[7]=g s4[8]=o
第一个lo的索引:3, 截取第一个lo之前的子串:hel, 最后一个lo的索引:9%  

你可能感兴趣的:(go语言学习,golang,开发语言,后端)