Go学习随笔(二)字符串的操作\遍历\索引\统计\替换\大小写转化\修改\插入\判断是否包含

在GO中字符串作为基本的类型,和c语言不同,c没有原生的字符串类型,c语言使用的是字符数组来表示字符串,并以字符指针来传递字符串。

1.字符串的表示

在Go语言中,字符串的值是不可变的,当创建一个字符串之后,无法再修改这个字符串内容,在GO中字符串是一个定长字符数组。

package main

import (
	"fmt"
)

var (
	value1 float64
)

func main() {
	s := "aA你2"
	fmt.Println("字符串长度:", len(s))
	for i := 0; i < len(s); i++ {
		fmt.Println(s[i])
	}

//结果是:字符串长度: 6
97  //a
65    //A
228    //你
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 main

import (
	"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?
true
true
true
true
false

索引

 在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次

}
结果:
3
1

字符数量

 

func main() {
	str := "你好世界"

	/*len([]rune(str))是两个方法的组合,先把字符串通过[]rune转化,然后统计长度*/
	fmt.Printf("%d\n", len([]rune(str)))
	
	/* 第二个方法是通过utf8包中的RuneCountInString函数统计,一般更推荐第二种,如果没有用utf8其他的函数可以没必要用这种方法用第一种也可以*/
	fmt.Println(utf8.RuneCountInString(str))
	

}

结果:
4
4

 大小写转化

 

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;厉害

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值