本文共 5666 字,大约阅读时间需要 18 分钟。
在GO中字符串作为基本的类型,和c语言不同,c没有原生的字符串类型,c语言使用的是字符数组来表示字符串,并以字符指针来传递字符串。
1.字符串的表示
在Go语言中,字符串的值是不可变的,当创建一个字符串之后,无法再修改这个字符串内容,在GO中字符串是一个定长字符数组。
package mainimport ( "fmt")var ( value1 float64)func main() { s := "aA你2" fmt.Println("字符串长度:", len(s)) for i := 0; i < len(s); i++ { fmt.Println(s[i]) }//结果是:字符串长度: 697 //a65 //A228 //你189 //你160 //你50 //2/* 下面代码会报错,字符串能不值不能修改*/ // s := "你好," // t := s s += "世界。" //字符串可以连接,但原字符不会改变 fmt.Println(s)//aA你2世界。}
非解释字符串
func main() { str1 := `苟利国家生死以,\n 岂因祸福避趋之` //注意!键盘tab上门那个 ~ 的按键的点 str2 := "今天天气\n真好" fmt.Println(str1) fmt.Println(str2)}结果:苟利国家生死以,\n 岂因祸福避趋之今天天气真好
注意上面的反单引号和双引号区别,首先单引号可以跨行,并且引号内的所有内容都会直接输出,包括转义字符换行,而双引号不能换行,且会解析转义字符。
操作字符串
func main() { s := "abcd你" fmt.Println(len(s)) // 长度7 for i := 0; i < len(s); i++ { fmt.Println(s[i]) } /* 输出 97 100 99 98 228 189 160 */ /*从上面字符串能看到汉字占3个字节,一共7个字节长度 */ // c := s[len(s)] // fmt.Println(len(s), c) /*这两行代码会报错,因为字符串没有这个索引值(从0开始算,长度是7,但是最后一个字节索引是6)*/ fmt.Println(s[0:7]) //s[0:7] 表示基于s字符串的第0个字节开始到第7字节(不包含第7个)生成一个新的字符串。生成的新字符串将包含7-0字节。也就是说如果要截取字符串,需要注意并不包含最后的那个字符。 fmt.Println(s[4:]) //返回 :你 fmt.Println(s[:3]) //返回 :adc fmt.Println(s[:4]) //返回 :abcd fmt.Println(s[:5]) //返回不出来 你 字 返回的是:abcd� fmt.Println(s[3:]) //返回 :d你}
连接字符串
func main() { s := "abcd你" fmt.Println(s[4:] + "好") //你好 fmt.Println(s[3:] + "好") //d你好 str := "你好," + "Go!" //由于编译器自动加分号的原因,加号必须放在第一行 fmt.Println(str) //你好,Go!}
字符串遍历
func main() { s := "我是一个中国人" for i := 0; i < len(s); i++ { fmt.Printf("%c", s[i]) fmt.Printf("%d=%v\n", i, s[i]) //输出单字节值 } fmt.Printf("\n")//使用这种方法无法输出我们想要的结果,因为单纯使用len方法是不能遍历字符串每个字符,只是遍历其一个字节是无法显示完成的字符串,因此遍历字符串要用range方式// For-each range 循环 这种格式的循环可以对字符串、数组、切片等进行迭代输出元素。 for _, v := range s { fmt.Printf("%c", v) } //输出:我是一个中国人 fmt.Printf("\n") t := []int{1, 2, 3, 4} for x, y := range t { fmt.Println(x, y) }//其中x是键,y是值 类似键值对输出 输出: 0 1 1 2 2 3 3 4}
字符串的修改
因为Go中字符串不能修改,也就是不能用s[i]的方式修改字符串的UTF-8编码,如果确实要修改 可以将字符串内容复制到另一个可写变量中,然后修改,一般用[]byte和[]rune格式,如果字符中的字节进行修改,则转换为[]rune格式,转换过程会自动复制数据
//[]byte格式func main() { s := "hello 世界" b := []byte(s) //转换为[]byte,自动复制数据 b[5] = ',' //修改[]byte fmt.Printf("%s\n", s) fmt.Printf("%s\n", b)}输出: hello 世界 hello,世界//[]rune格式func main() { s := "hello 世界" r := []rune(s) //转换为[]rune,自动复制数据 r[6] = '中' //修改[]rune r[7] = '国' fmt.Println(s) //s不能被修改 fmt.Println(string(r)) //转换为字符串,又一次复制数据}输出: hello 世界 hello 中国
包含判断(前后缀包含)
对于基本类型来说,字符串执行操作会比较复杂, Go语言标准库中有一个名为strings的库
package mainimport ( "fmt" "strings" //stings包)var ( value12 float64)func main() { str := "This is an example of a string" fmt.Printf("Dose the string \"%s\" have have prftix %s?", str, "Th") fmt.Printf("\n") fmt.Printf("%t\n", strings.HasPrefix(str, "Th")) //HasPrefix判断前缀是否包含指定字符串 fmt.Printf("%t\n", strings.HasSuffix(str, "string")) //HasSuffix判断后缀是否包含指定字符串 fmt.Printf("%t\n", strings.Contains(str, "example")) //contains 判断是否包含指定字符串 fmt.Println(strings.Contains("foo", "")) //ture fmt.Println(strings.ContainsAny("foo", "")) //false //Contains和ContainsAny不同的点在于,第二个能够匹配更广泛的内容,它可以容纳Unicode字符}返回结果:Dose the string "This is an example of a string" have have prftix Th?truetruetruetruefalse
索引
在strings包中Index就可以返回指定字符/串的第一个字符索引值,如果不存在相应的字符串,则返回-1。
func main() { str := "Hi, I'm Job, Hi." fmt.Printf("%d\n", strings.Index(str, "J")) // 8 fmt.Printf("%d\n", strings.Index(str, "H")) // 0 fmt.Printf("%d\n", strings.Index(str, "Fuck")) //-1}
非ascll编码字符可以用IndexRune函数对字符进行定位
func main() { str := "我是张三" fmt.Printf("%d\n", strings.IndexRune(str, '张')) //6}
替换
替换字符串最常用的方法是用正则匹配去替换,灵活度更高,但是Go语言对于比较基础的字符串替换已经打包在strings中了,例如:Replace函数
func main() { str := "我是张三" new := "李四" old := "张三" n := 1 fmt.Println(strings.Replace(str, old, new, n)) /*其中n参数表示匹配到第几个old,如果n为-1则代表匹配所有*/}结果:我是李四
统计
func main() { str := "Golang is cool, right?" var many0 = "o" fmt.Printf("%d\n", strings.Count(str, many0)) // o 出现3次 fmt.Printf("%d\n", strings.Count(str, "oo")) // oo 出现1次}结果:31
字符数量
func main() { str := "你好世界" /*len([]rune(str))是两个方法的组合,先把字符串通过[]rune转化,然后统计长度*/ fmt.Printf("%d\n", len([]rune(str))) /* 第二个方法是通过utf8包中的RuneCountInString函数统计,一般更推荐第二种,如果没有用utf8其他的函数可以没必要用这种方法用第一种也可以*/ fmt.Println(utf8.RuneCountInString(str)) }结果:44
大小写转化
var ( lower string upper string)func main() { str := "How are you?" fmt.Printf("%s\n", str) fmt.Printf("%s\n", strings.ToLower(str)) //ToLower转化成小写 fmt.Printf("%s\n", strings.ToUpper(str)) //ToUpper转化成大写}结果:How are you?how are you?HOW ARE YOU?
修剪
func main() { str := "!!! Go !!!" fmt.Printf("%q\n", strings.Trim(str, "! ")) fmt.Printf("%q\n", strings.Trim(str, " ! ")) fmt.Printf("%q\n", strings.Trim(str, "!")) //注意第二个参数区别会造成什么结果 str1 := "女朋友是最美的" fmt.Printf("%q\n", strings.Trim(str1, "女")) fmt.Printf("%q\n", strings.Trim(str1, "的")) fmt.Printf("%q\n", strings.Trim(str1, "女最")) //只减掉一个女字 最字没有减掉}结果:"Go""Go"" Go ""朋友是最美的""女朋友是最美""朋友是最美的"
分割
func main() { fmt.Printf("%q\n", strings.Split("a,b,c", ",")) fmt.Printf("%q\n", strings.Split("a boy a computer a pig", "a")) fmt.Printf("%q\n", strings.Split("qwe", ""))}结果:["a" "b" "c"]["" " boy " " computer " " pig"]["q" "w" "e"]
插入
func main() { str := "The quick brown fox jumps over the lazy dog 厉害" strSli := strings.Fields(str) //strings.Fields函数用于把字符串转换为字符串切片,然后听过range获得每个切片的值,最后使用string.Join向字符串插入指定字符,除此之外还能使用字节缓冲bytes.Buffer连接字符串 fmt.Printf("%s\n", strSli) for _, val := range strSli { fmt.Printf("%s ", val) } fmt.Println() //换行 str2 := strings.Join(strSli, ";") fmt.Printf("%s\n", str2)}结果:[The quick brown fox jumps over the lazy dog 厉害]The quick brown fox jumps over the lazy dog 厉害 The;quick;brown;fox;jumps;over;the;lazy;dog;厉害
转载地址:http://qpqen.baihongyu.com/